thi*_*khy 2 regex perl mainframe jcl
我写了一个Perl函数来替换JCL脚本中的作业名称.这里使用了零宽度匹配.
sub modify_jcl_jobname ()
{
my ($jcl, $old, $new) = @_;
$jcl =~ s/
# The name must begin in column 3.
^(?<=\/\/)
# The first charater must be alphabetic or national.
($old)
# The name must be followed by at leat on blank.
# Append JCL keyword JOB
(?=\s+JOB)
/$new/xmig; # Multi-lines, ignore case.
return $jcl;
}
Run Code Online (Sandbox Code Playgroud)
但是这个功能直到我做了一个简单的修改才删除了前导符号"^"后才起作用.
#before ^(?<=\/\/)
#after (?<=\/\/)
Run Code Online (Sandbox Code Playgroud)
所以我想说明问题的原因.任何回复将不胜感激.谢谢.
问题在于
^(?<=\/\/)
Run Code Online (Sandbox Code Playgroud)
只有匹配的点^之前有两个字符,该模式才会匹配//.这种情况永远不会发生,因为/^/m匹配字符串的开头和换行符之后.
但是你不想在行的开头开始匹配.你想开始匹配2个字符.你想要的实际上是:
(?<=^\/\/)
Run Code Online (Sandbox Code Playgroud)
在做了一些改进之后,代码看起来像:
sub modify_jcl_jobname {
my ($jcl, $old, $new) = @_;
$jcl =~ s{
(?<= ^// )
\Q$old\E
(?= \s+ JOB )
}{$new}xmig;
return $jcl;
}
Run Code Online (Sandbox Code Playgroud)
改进:
()).它强制调用者告诉Perl忽略原型(通过使用&).\Q...\E)以将内容$old转换为正则表达式模式.(...)).s///到s{}{})切换到需要更少的转义.优化器可能会更好地处理此版本:
$jcl =~ s{
^// \K
\Q$old\E
(?= \s+ JOB )
}{$new}xmig;
Run Code Online (Sandbox Code Playgroud)