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。これは非効率的であるだけでなく、引用の問題($ replaceのすべてが構文的に有効なPerlであることを確認する必要があります)とセキュリティホール($ replaceが実行時に生成される場合、特に外部ソースからのものである場合)があります。私の最も嫌いなアプローチ:

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 に答える