How can I expand variables in text strings?
如果可以避免,请不要这样做,或者如果您可以使用模板系统,例如 Text::Template 或 Template Toolkit,请改为这样做。您甚至可以使用sprintf 或printf 完成工作:
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 变成了“Fred”,这就是字符串中剩下的内容:
$string =~ s/(\$\w+)/$1/eeg; # 'Say hello to Fred and Barney'
/e 也会默默地忽略严格的违规,用空字符串替换未定义的变量名。由于我使用了/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;