3

私のperlスクリプトでは、$configディレクトリの両方のバージョンが必要です:

my $config='$home/client/config';

my $config_resolved="$home/client/config";

しかし、私はから取得$config_resolvedしたい$config、つまり次のようなもの:

my $config_resolved=resolve_vars($config);

どのように私はperlでそのようなことをすることができますか?

4

4 に答える 4

5

Perl FAQから(すべての Perl プログラマーが少なくとも一度は読む必要があります):

テキスト文字列内の変数を展開するにはどうすればよいですか?

(ブライアン・フォイによる寄稿)

回避できる場合は、使用しないでください。または、Text::Template や Template Toolkit などのテンプレート システムを使用できる場合は、代わりにそれを使用してください。sprintfまたはで仕事を終わらせることさえできるかもしれません printf

my $string = sprintf 'Say hello to %s and %s', $foo, $bar;

ただし、完全なテンプレート システムを引き出したくないという 1 回限りの単純なケースでは、2 つの Perl スカラー変数を含む文字列を使用します。この例では、変数の値に展開$fooしたいと思います。$bar

my $foo = 'Fred';
my $bar = 'Barney';
$string = 'Say hello to $foo and $bar';

これを行う方法の 1 つは、置換演算子と二重/eフラグを使用することです。最初のものは置換側で/e評価され、それを に変換します。2 番目は で始まり、その値に置き換えられます。、次に「Fred」に変わり、それが最終的に文字列に残ります。$1$foo/e$foo$foo

$string =~ s/(\$\w+)/$1/eeg; # 'Say hello to Fred and Barney'

はまた/e、strict の違反を黙って無視し、未定義の変数名を空の文字列に置き換えます。私は/eフラグを使用しているため (2 回も!)、文字列形式の eval と同じセキュリティ問題をすべて抱えています。に何か変なところがあれば$foo、おそらくのようなもの@{[ system "rm -rf /" ]}で、私がトラブルに巻き込まれる可能性があります。

セキュリティの問題を回避するために、変数名を評価する代わりに、ハッシュから値を取得することもできます。単一/eの を使用して、ハッシュをチェックして値が存在することを確認できます。存在しない場合は、欠落している値をマーカーに置き換えることができます。この場合、 ???何かを見逃したことを通知します。

my $string = 'This has $foo and $bar';
my %Replacements = (
    foo  => 'Fred',
    );
# $string =~ s/\$(\w+)/$Replacements{$1}/g;

$string =~ s/\$(\w+)/
            exists $Replacements{$1} ? $Replacements{$1} : '???'
            /eg;
print $string;
于 2012-06-26T09:43:13.210 に答える
2

これに使いますeval。そのため、すべてのスカラー (名前) をその値に置き換える必要があります。

$config = 'stringone';
$boo = '$config/any/string';
$boo =~ s/(\$\w+)/eval($1)/eg;
print $boo;
于 2012-06-26T06:36:16.640 に答える
1

my を使用してプライベート変数として宣言しているため、/ee修飾子を使用することもできます。これにより、ローカル スコープ内にあると宣言された変数を見つけることができます。

$boo =~ s/(\$\w+)/$1/eeg;
于 2012-06-26T07:23:40.280 に答える
-1

これは、 の double-eval 修飾子によって最も整然と安全に行われs///ます。

以下のプログラムでは、1 つ目/eは文字列$1$home評価して get を取得し、2 つ目は評価$homeして変数の値を取得しますHOME

use strict;

my $home = 'HOME';

my $config = '$home/client/config';

my $config_resolved = resolve_vars($config);

print $config_resolved, "\n";

sub resolve_vars {
  (my $str = shift) =~ s/(\$\w+)/$1/eeg;
  return $str;
}

出力

HOME/client/config
于 2012-06-26T11:50:37.860 に答える