如何用单条Perl正则实现$替换为$$(排除特定后续字符)
Perl正则实现$字符的精准替换
需求
将字符串中的$替换为$$,但满足以下条件时不替换该$:
$后面紧跟^、@、($前面是$(即连续的$$)
示例
输入
$(bar) $@ $$.z $^.zh $(foo) $foo $bar
期望输出
$(bar) $@ $$.z $^.zh $(foo) $$foo $$bar
现有方案的问题
尝试的正则无法正确处理$$场景,会将$$.z错误替换为$$$.z:
my $var = ' $(bar) $@ $$.z $^.zh $(foo) $foo $bar '; print "$var\n"; my $d = '$'; $var =~ s/\$([^\@\(\$\^])/$d$d$1/g; print "$var\n";
解决方案:使用双向环视断言的单条正则
利用Perl的负向后行断言和负向先行断言实现精准匹配,只替换符合要求的$:
my $var = ' $(bar) $@ $$.z $^.zh $(foo) $foo $bar '; print "原字符串:$var\n"; # 方案1:使用转义字符表示字面量$ $var =~ s/(?<!\$)\$(?!([\@\(\^]))/\$\$/g; # 方案2:使用e修饰符执行字符串替换,避免特殊变量解析 # $var =~ s/(?<!\$)\$(?!([\@\(\^]))/'$$'/eg; print "替换后:$var\n";
正则规则解释
(?<!\$):负向后行断言,确保当前匹配的$前面没有另一个$,避免替换连续$$中的第二个$\$:匹配字面量$字符(?!([\@\(\^])):负向先行断言,确保当前匹配的$后面没有@、(、^中的任意一个,避免替换自动变量/函数调用类的$\$\$:替换为两个字面量$,Perl中$是特殊字符需转义;若用'$$'加e修饰符,会直接将单引号内的内容作为替换结果
内容的提问来源于stack exchange,提问作者Peeter Joot
相关产品推荐
相关产品推荐

