Mal*_*ala 5 regex perl replace
基本上,我要做的是搜索一个相当大的PHP文件,并用其他代码替换包含字符串"search_term"的任何PHP代码块.即
<?php
//some stuff
?>
<?php
// some more stuff
$str = "search_term";
// yes...
?>
<?php
// last stuff
?>
Run Code Online (Sandbox Code Playgroud)
应该成为
<?php
//some stuff
?>
HELLO
<?php
// last stuff
?>
Run Code Online (Sandbox Code Playgroud)
到目前为止我得到的是
$string =~ s/<\?php(.*?)search_term(.*?)\?>/HELLO/ims;
Run Code Online (Sandbox Code Playgroud)
这与最接近的闭合正确匹配?>,但在最开始时匹配<?php,而不是最接近字符串的匹配search_term.
我究竟做错了什么?
一般来说,我不喜欢使用非贪婪匹配,因为它通常会导致这样的问题.Perl查看你的文件,找到第一个'<?php',然后开始寻找其余的regexp.它通过第一个'?>'和第二个'<?php'因为它们匹配.*,然后找到search_term和下一个'?>',它就完成了.
非贪婪匹配意味着你有一个正常的表达式,它匹配的东西比你真正想要的更多,并且它将它留给perl来决定返回哪个匹配.最好使用与您想要匹配的正则匹配的正则表达式.在这种情况下,您可以使用((?!\?>).)*而不是.*?((?!\?>)是一个负面的前瞻断言)来获得您想要的内容
s/<\?php((?!\?>).)*search_term((?!\?>).)*\?>/HELLO/is;
Run Code Online (Sandbox Code Playgroud)
如果您希望多次匹配,则可能需要使用/isg而不是/is.
或者,只需将文件拆分为块:
@blocks = split /(\?>)/, $string;
while (@blocks) {
$block = shift @blocks;
$sep = shift @blocks;
if ($block=~/search_term/) {
print "HELLO";
} else {
print $block, $sep;
}
}
Run Code Online (Sandbox Code Playgroud)