1

我正在尝试在替换字符串中使用变量插值,包括$1, $2,... 但是,我无法将其扩展$1到替换中。我最终将从 配置文件中读取$pattern$replacement变量,但即使手动设置它们也不起作用。

在示例脚本中,您可以看到$1(应该是'DEF')没有在 中展开$new_name,而是在$new_name2(没有变量)中。

在替换中添加“e”标志没有帮助。

我该如何解决?

马特

示例代码:

#!/usr/local/bin/perl
use strict;

my $old_name = 'ABC_DEF_GHI';

my $pattern = 'ABC_(...)_GHI';
my $replacement = 'CBA_${1}_IHG';

# using variables - doesn't work
my $new_name = $old_name;
$new_name =~ s|$pattern|$replacement|;

printf("%s --> %s\n", $old_name, $new_name);


# not using variables - does work
my $new_name2 = $old_name;
$new_name2 =~ s|ABC_(...)_GHI|CBA_${1}_IHG|;

printf("%s --> %s\n", $old_name, $new_name2);

输出:

ABC_DEF_GHI --> CBA_${1}_IHG
ABC_DEF_GHI --> CBA_DEF_IHG
4

2 回答 2

2

您需要在代码中进行此更改:

my $replacement = '"CBA_$1_IHG"';  #note the single and double quotes
# ...
$new_name =~ s|$pattern|$replacement|ee;  #note the double "ee", double evaluation

有关更多信息,请参阅此 SO 答案

于 2013-05-01T20:10:30.600 回答
2

/e视为$replacementPerl 代码。Perl 代码$replacement只返回它包含的值。

如果你想评估 Perl 代码的内容$replacement你需要

s/$search/ my $s = eval $replacement; die $@ if $@; $s /e

可以写成

s/$search/$replacement/ee

请注意,由于$replacement预期包含 Perl 代码,这意味着它可以用于执行任意 Perl 代码。

更好的解决方案是意识到您正在编写自己的低于标准的模板系统,并改用现有的。String::Interpolate理解您当前使用的模板语法:

use String::Interpolate qw( interpolate );
s/$search/interpolate $replace/e
于 2013-05-01T21:12:56.380 回答