我想搜索和替换一个简单的字符串,仅在每行有这么多匹配之后才开始,例如:
n=2 的 s/ZZ/YY
xxxZZxxxxxxZZxxxxZZxZZxxxxZZ
xZZxxxZZxxZZxxZZxZZxxxZZxxx
...
进入:
xxxZZxxxxxxZZxxxxxYYxxxxYY
xZZxxxZZxxYYxxYYxYYxxxYYxxx
...
在我的问题中,连续的“ZZ”之间总会有一个“x”。提前致谢。
我建议一个可执行的替换字符串,它可以让你计算到目前为止看到的匹配数
这段代码演示
use strict;
use warnings;
while (<DATA>) {
my $n = 0;
s/(ZZ)/$n++ < 2 ? $1 : 'YY'/eg;
print;
}
__DATA__
xxxZZxxxxxxZZxxxxZZxZZxxxxZZ
xZZxxxZZxxZZxxZZxZZxxxZZxxx
输出
xxxZZxxxxxxZZxxxxYYxYYxxxxYY
xZZxxxZZxxYYxxYYxYYxxxYYxxx
可能有向后看的解决方案,或者反向字符串和向前看并再次反向的解决方案(如果有,我会支持它们),但我通常会找到解决while
方案更容易发现,并且可以说更容易阅读。
1 while $string =~ s/(ZZ.*ZZ.*)ZZ/$1YY/
也就是说,虽然字符串包含三种ZZ
模式,但将第三种模式替换为YY
.
作为一般解决方案:
$expr = (quotemeta($pattern1) . ".*") x $n;
1 while $string =~ s/($expr)\Q$pattern2\E/$1$pattern2/;
It seems like the simplest perl solution should be: 1 while s/ZZ/YY/3
, but perl does not accept that. So do the same with sed
:
sed ':a
s/ZZ/YY/3
ta'
Some implementations of sed
allow this to be written more simply: sed ':a; s/ZZ/YY/3; ta'
, and I believe it is fully portable to write: sed -e :a -e s/ZZ/YY/3 -e ta
1 while $thisline=~s/((?:x*?ZZx*?){2}[xZY]*?)ZZ/$1YY/;
That is a solution for n=2.
You can just change the number there for other values of n.
Also, I optimized the substitution with lazy matching and by doing away with superfluous capturing.