$s = "bla..bla";
$s =~ s/([^%])\./$1/g;
Run Code Online (Sandbox Code Playgroud)
我认为它应该取代所有出现的.那以后是不是%与之前的字符..
但那$s是:bla.bla但它应该是blabla.问题出在哪儿?我知道我可以使用量词,但我需要这样做.
当全局正则表达式搜索字符串时,它将找不到重叠匹配.
你的字符串中的第一个匹配将被a.替换为a.当正则表达式引擎恢复搜索时,它会从下一个开始,.因此它看作.bla是字符串的其余部分,并且你的正则表达式需要一个字符匹配才能.再次匹配.
相反,使用负向lookbehind来执行前一个字符不是的断言%:
$s =~ s/(?<!%)\.//g;
Run Code Online (Sandbox Code Playgroud)
请注意,如果您使用正面的lookbehind (?<=[^%]),则不会替换.if它是字符串中的第一个字符.
问题在于,即使使用/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)
这将消除任何.是不是由之前%,即使它是字符串中的第一个字符.