Non*_*ame 6 regex perl substitution
请考虑以下示例:
my $text = "some_strange_thing";
$text =~ s/some_(\w+)_thing/no_$1_stuff/;
print "Result: $text\n";
Run Code Online (Sandbox Code Playgroud)
它打印
"结果:没有奇怪的 _粮"
到现在为止还挺好.
现在,我需要从外部源(用户输入,配置文件等)获取匹配和替换模式.天真的解决方案似乎是这样的:
my $match = "some_(\\w+)_thing";
my $repl = "no_\$1_stuff";
my $text = "some_strange_thing";
$text =~ s/$match/$repl/;
print "Result: $text\n";
Run Code Online (Sandbox Code Playgroud)
然而:
"结果:no_ $ 1 _stuff".
怎么了?如何通过外部提供的模式获得相同的结果?
解决方案1: String::Substitution
use String::Substitution qw(gsub_modify);
my $find = 'some_(\w+)_thing';
my $repl = 'no_$1_stuff';
my $text = "some_strange_thing";
gsub_modify($text, $find, $repl);
print $text,"\n";
Run Code Online (Sandbox Code Playgroud)
替换字符串仅插入(松散使用的术语)编号匹配变量(如
$1或${12}).有关更多信息,请参阅"interpolate_match_vars".
该模块并不能保存或插值$&避免了"相当大的性能损失"(参见perlvar).
解决方案2: Data::Munge
这是Grinnz在下面的评论中提到的解决方案.
将Data::Munge可以使用以下方法:
use Data::Munge;
my $find = qr/some_(\w+)_thing/;
my $repl = 'no_$1_stuff';
my $text = 'some_strange_thing';
my $flags = 'g';
print replace($text, $find, $repl, $flags);
# => no_strange_stuff
Run Code Online (Sandbox Code Playgroud)
解决方案3:快速的方式(如果替换不包含双引号并且不考虑安全性)
免责声明:我提供此解决方案,因为这种方法可以在网上找到,但其解释并未解释.不要在生产中使用它.
使用这种方法,您不能拥有包含"双引号的替换字符串,因为这相当于处理编写配置文件直接代码访问权限的人,因此不应向Web用户公开(如Daniel Martin所述)).
您可以使用以下代码:
#!/usr/bin/perl
my $match = qr"some_(\w+)_thing";
my $repl = '"no_$1_stuff"';
my $text = "some_strange_thing";
$text =~ s/$match/$repl/ee;
print "Result: $text\n";
Run Code Online (Sandbox Code Playgroud)
请参阅IDEONE演示
结果:
Result: no_strange_stuff
Run Code Online (Sandbox Code Playgroud)
你必须
'"..."'以便$1以后可以评估/ee强制变量的双重评价的替代品.专门用于搜索和替换的
s///e修饰符是评估修饰符.s///e将替换文本视为Perl代码,而不是双引号字符串.代码返回的值将替换匹配的子字符串.s///e如果您需要在替换文本的过程中进行一些计算,这将非常有用.
您可以使用qr实例化regex(qr"some_(\w+)_thing")的模式.