我知道匹配,prematch和postmatch预定义变量。我想知道s ///运算符的评估替换部分是否有类似的东西。
这在动态表达式中特别有用,因此不必在第二次进行评估。
例如,我目前有%regexs,它是各种搜索和替换字符串的散列。
这是一个片段:
while (<>) {
foreach my $key (keys %regexs) {
while (s/$regexs{$key}{'search'}/$regexs{$key}{'replace'}/ee) {
# Here I want to do something with just the replaced part
# without reevaluating.
}
}
print;
}
有方便的方法吗? Perl似乎有这么多方便的快捷方式,两次评估似乎是一种浪费(这似乎是替代方案)。
编辑:我只想举个例子:$ regexs {$ key} {'replace'}可能是字符串'“$ 2 $ 1”'因此交换了某些文字的位置string $ regexs {$ key} {'search'}可能是'(foo)(bar)' - 因此导致“barfoo”。我试图避免的第二个评估是$ regexs {$ key} {'replace'}的输出。
答案 0 :(得分:2)
您可以定义代码引用来完成工作,而不是使用字符串eval
(我假设它是s///ee
的内容)。然后,这些代码引用可以返回替换文本的值。例如:
use strict;
use warnings;
my %regex = (
digits => sub {
my $r;
return unless $_[0] =~ s/(\d)(\d)_/$r = $2.$1/e;
return $r;
},
);
while (<DATA>){
for my $k (keys %regex){
while ( my $replacement_text = $regex{$k}->($_) ){
print $replacement_text, "\n";
}
}
print;
}
__END__
12_ab_78_gh_
34_cd_78_yz_
答案 1 :(得分:1)
我很确定没有任何直接的方法来做你所要求的,但这并不意味着它是不可能的。怎么样?
{
my $capture;
sub capture {
$capture = $_[0] if @_;
$capture;
}
}
while (s<$regexes{$key}{search}>
<"capture('" . $regexes{$key}{replace}) . "')">eeg) {
my $replacement = capture();
#...
}
好吧,除了要做得非常好,你必须在那里做一些代码,以便在一个单一的字符串(反斜杠单引号和反斜杠)中使哈希值保持安全。
答案 2 :(得分:1)
如果您手动执行第二个eval,则可以自行存储结果。
my $store;
s{$search}{ $store = eval $replace }e;
答案 3 :(得分:0)
为什么不在之前分配到本地变量:
my $replace = $regexs{$key}{'replace'};
现在你的评估一次。