如何用其前辈替换所有出现的某些字符?

Kra*_*rab 2 regex perl

$s = "bla..bla";
$s =~ s/([^%])\./$1/g;
Run Code Online (Sandbox Code Playgroud)

我认为它应该取代所有出现的.那以后是不是%与之前的字符..

但那$s是:bla.bla但它应该是blabla.问题出在哪儿?我知道我可以使用量词,但我需要这样做.

And*_*ark 9

当全局正则表达式搜索字符串时,它将找不到重叠匹配.

你的字符串中的第一个匹配将被a.替换为a.当正则表达式引擎恢复搜索时,它会从下一个开始,.因此它看作.bla是字符串的其余部分,并且你的正则表达式需要一个字符匹配才能.再次匹配.

相反,使用负向lookbehind来执行前一个字符不是的断言%:

$s =~ s/(?<!%)\.//g;
Run Code Online (Sandbox Code Playgroud)

请注意,如果您使用正面的lookbehind (?<=[^%]),则不会替换.if它是字符串中的第一个字符.


rua*_*akh 6

问题在于,即使使用/g标志,每次替换都会开始查看前一个替换的位置.你试图替换a.,a然后a.a,但第二次替换不会发生,因为a已被先前的替换"吞噬".

一个解决方法是使用零宽度lookbehind断言:

$s =~ s/(?<=[^%])\.//g;
Run Code Online (Sandbox Code Playgroud)

这将去除任何.字符串中的第一个字符,并且被由前面%.

但你可能真的想要这个:

$s =~ s/(?<!%)\.//g;
Run Code Online (Sandbox Code Playgroud)

这将消除任何.不是由之前%,即使它字符串中的第一个字符.