如何显式解析perl字符串中的变量?

时间:2012-06-26 06:26:17

标签: string perl

在我的perl脚本中,我希望有两个版本的$config目录:

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

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

但我想从$config_resolved获取$config,即类似的内容:

my $config_resolved=resolve_vars($config);

我怎样才能在perl中做这样的事情?

4 个答案:

答案 0 :(得分:4)

来自Perl FAQ(每个Perl程序员应至少阅读一次):

  

How can I expand variables in text strings?

     

(由brian d foy提供)

     

如果你可以避免它,不要,或者你可以   使用模板系统,如Text :: Template或Template Toolkit,   那样做。您甚至可以完成工作   sprintfprintf

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

然而,对于一次性简单的情况,我不想拔出一个   完全模板系统,我将使用一个有两个Perl标量的字符串   变量在里面。在此示例中,我想将$foo$bar扩展为   他们的变量值:

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

我可以这样做的一种方法是使用替换运算符和双/e标志。该   第一个/e评估替换方$1并将其转换为$foo。该   第二个/e$foo开头,并将其替换为其值。 $foo,   然后,变成'弗雷德',这就是字符串中剩下的东西:

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

/e也会默默地忽略违反严格的行为,取代undefined   带有空字符串的变量名。因为我正在使用/e标志   (甚至两次!),我遇到了所有相同的安全问题   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;

答案 1 :(得分:2)

我使用eval。 因此,您必须将所有标量(名称)替换为其值。

$config = 'stringone';
$boo = '$config/any/string';
$boo =~ s/(\$\w+)/eval($1)/eg;
print $boo;

答案 2 :(得分:1)

因为您使用my将其声明为私有变量,所以您也可以使用 / ee 修饰符。这可以找到声明在本地范围内的变量:

$boo =~ s/(\$\w+)/$1/eeg;

答案 3 :(得分:-1)

s///上的双重修改器最为整洁,安全。

在下面的程序中,第一个/e评估字符串$1以获取$home,而第二个评估$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