我写了一个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;
}
但是直到我做了一个简单的修改才删除了前导符号“^”,这个功能才起作用。
#before ^(?<=\/\/)
#after (?<=\/\/)
所以我想说明问题的原因。任何回复将不胜感激。感谢。
答案 0 :(得分:8)
问题在于
^(?<=\/\/)
只有^
匹配的地点前面有两个字符//
时,该模式才会匹配。这是永远不会发生的,因为/^/m
匹配字符串的开头和换行符之后。
但是你不想在行的开头开始匹配。你想开始匹配2个字符。你想要的实际上是:
(?<=^\/\/)
在做了一些改进后,代码如下:
sub modify_jcl_jobname {
my ($jcl, $old, $new) = @_;
$jcl =~ s{
(?<= ^// )
\Q$old\E
(?= \s+ JOB )
}{$new}xmig;
return $jcl;
}
改进:
()
)。它强制调用者告诉Perl忽略原型(使用&
)。\Q...\E
)以将$old
的内容转换为正则表达式模式,然后再使用它。(...)
)。s///
到s{}{}
)以减少转义。优化器可能会更好地处理此版本:
$jcl =~ s{
^// \K
\Q$old\E
(?= \s+ JOB )
}{$new}xmig;
答案 1 :(得分:3)
^
符号与该行的开头匹配。然后你想要一些前面有两个斜杠的东西 - 如果下一个字符是该行的第一个字符,这些斜杠应该在哪里?
s{^//
($old)
...
}{//$new}xmig
应该有效:你不需要看后面。
更新:感谢ikegami,我现在明白你使用它的原因了。您希望将//
保留在字符串中:嗯,您可以在替换中重复这些内容,或将^
字符移动到后面。