有没有办法在替换中使用变量作为修饰符?
my $search = 'looking';
my $replace = '"find: $1 ="';
my $modifier = 'ee';
s/$search/$replace/$modifier;
我需要使用哈希数组来使用不同的修饰符进行批量搜索替换。
答案 0 :(得分:4)
如果你戴上护目镜和零除套装,你可以使用eval
。
E.g:
use strict;
use warnings;
sub mk_re {
my ($search, $replace, $modifier) = @_;
$modifier ||= '';
die "Bad modifier $modifier" unless $modifier =~ /^[msixge]*$/;
my $sub = eval "sub { s/($search)/$replace/$modifier; }";
die "Error making regex for [$search][$replace][$modifier]: $@" unless $sub;
return $sub;
}
my $search = 'looking';
my $replace = '"find: $1 ="';
my $modifier = 'e';
# Sub can be stored in an array or hash
my $sub = mk_re($search, $replace, $modifier);
$_ = "abc-looking-def";
print "$_\n";
$sub->();
print "$_\n";
答案 1 :(得分:4)
虽然使用eval
编译新替换的方法可能是最直接的,但您可以创建更模块化的替换:
use warnings;
use strict;
sub subst {
my ($search, $replace, $mod) = @_;
if (my $eval = $mod =~ s/e//g) {
$replace = qq{'$replace'};
$replace = "eval($replace)" for 1 .. $eval;
} else {
$replace = qq{"$replace"};
}
sub {s/(?$mod)$search/$replace/ee}
}
my $sub = subst '(abc)', 'uc $1', 'ise';
local $_ = "my Abc string";
$sub->();
print "$_\n"; # prints "my ABC string"
这只是经过了轻微的测试,它留给读者练习其他标志,如g
答案 2 :(得分:3)
use warnings;
use strict;
my @stuff = (
{
search => "this",
replace => "that",
modifier => "g",
},
{
search => "ono",
replace => "wendy",
modifier => "i",
}
);
$_ = "this ono boo this\n";
for my $h (@stuff) {
if ($h->{modifier} eq 'g') {
s/$h->{search}/$h->{replace}/g;
} elsif ($h->{modifier} eq 'i') {
s/$h->{search}/$h->{replace}/i;
}
# etc.
}
print;
您可能想要使用的修饰符很多,所以我认为这很容易。
你可以使用eval
,但它非常混乱。
答案 3 :(得分:2)
当然s/$search/$replace/
按预期工作。动态修饰符不是直截了当的。
对于pimsx
的常规匹配modifiers,您可以使用Perl的Extended Patterns动态修改修饰符标记作为模式的一部分。它们的形式为(?pimsx-imsx)
以打开/关闭这些修饰符。
对于s//
e
和ee
表单,您可以使用相同perlre部分中记录的(?{ perl code})
。对于所有eval
e
或ee
表单,请考虑结果代码的安全性!
没有任何形式可以修改我所知道的全局到第一场比赛,因此全局vs第一场比赛需要是单独的声明。
答案 4 :(得分:2)
这是Kinopiko的回答和评估的组合。
此处使用 eval
以受控和可维护的方式生成查找表,并使用查找表来保存所有if ... elsif .. elsif,这些都不太容易看到。< / p>
(非常轻微的测试)
my @stuff = (
{
search => "this",
replace => "that",
modifier => "g",
},
{
search => "ono",
replace => "wendy",
modifier => "i",
}
);
$_ = "this ono boo this\n";
my @modifiers = qw{m s i x g e};
my $s_lookup = {};
foreach my $modifier (@modifiers) {
$s_lookup->{$modifier} = eval " sub { s/\$_[0]/\$_[1]/$modifier } ";
}
for my $h (@stuff) {
$s_lookup->{$h->{modifier}}->($h->{search},$h->{replace});
}
print;
要完全有用,这需要: