0
$test='abc="def"';
$replacement='$1="ghj"';
$test =~ s/(.+)="(.+)"/"$replacement/;
print $test;

它打印:

$1=ghj

我该如何对待$replacement被解释?

4

2 回答 2

6

您将/e修饰符添加到您的正则表达式。您还需要修改替换字符串,以便对其进行正确评估。需要双重评估来插入变量。

my $test='abc="def"';
my $replacement='"$1=ghj"';
$test =~ s/(.+)="(.+)"/$replacement/ee;
print $test;

输出:

abc=ghj

应该注意的是,这有点不安全,特别是如果其他人会影响您的替换价值。然后他们可以在您的系统上执行任意代码。

于 2012-11-29T03:41:37.823 回答
4

这个问题大约有3个答案。

  • 您的替换“字符串”实际上是要在匹配时评估以生成替换字符串的代码。也就是说,它更好地表示为一个函数:

my $test = 'abc="def"';
my $replacement = sub { $1 . '="ghj"' };
$test =~ s/(.+)="(.+)"/$replacement->()/e;
print $test;
  • 如果您不需要任意 Perl 表达式的全部功能(或者如果您的替换字符串来自外部源),您也可以将其视为模板来填充匹配结果。有一个模块以类似 JavaScript 的replace函数的形式封装了它,Data::Munge

use Data::Munge qw(replace);
my $test = 'abc="def"';
my $replacement = '$1="ghj"';
$test = replace $test, qr/(.+)="(.+)"/, $replacement;
print $test;
  • 最后,您可以将 Perl 代码表示为要eval'd 的字符串。这不仅效率低下,而且还充满了引用问题(您必须确保 $replacement 中的所有内容在语法上都是有效的 Perl)和安全漏洞(如果 $replacement 是在运行时生成的,特别是如果它来自外部源)。我最不喜欢的方法:

my $test = 'abc="def"';
my $replacement = '$1 . "=\\"ghj\\""';
$test =~ s/(.+)="(.+)"/eval $replacement/e;
print $test;

(这s//eval $foo/e部分也可以写成s//$foo/ee。我不喜欢这样做,因为eval它是邪恶的,不应该比现在更隐蔽。)

于 2012-11-29T03:56:48.330 回答