我有一个名为'input.file'的文件,其中包含以下行:
Foo是$ COLOR
$ COLOR被指定为'red',我正在尝试使用以下行创建名为'output.file'的第二个文件:
Foo是红色的
这是我失败的尝试:
#!/usr/bin/perl
use strict;
use warnings;
my $COLOR = "red";
open(FILE_IN, "< input.file");
open(FILE_OUT, "> output.file");
while (<FILE_IN>){
# Prints 'Foo is $COLOR' to 'output.file'
print FILE_OUT;
}
close FILE_IN;
close FILE_OUT;
# Prints 'Foo is red' to STDOUT
print "Foo is $COLOR\n";
那么当打印到'output.file'时,如何打印'red'而不是'$ COLOR'?
由于
答案 0 :(得分:4)
让我们假设一个字符串包含与正则表达式/\$\w+/
匹配的占位符。我们还有一个哈希映射名称到值,例如:
my %replacements = (
COLOUR => 'red',
x => 42,
perl_snippet => '$x++ == 3',
);
所以输入
my $input = <<'END';
My favourite colour is $COLOUR.
The meaning of life is $x. Here is some Perl: `$perl_snippet`
$undefined
END
应转换为
My favourite colour is red.
The meaning of life is 42. Here is some Perl: `$x++ == 3`
$undefined
和不
My favourite colour is red.
The meaning of life is 42. Here is some Perl: `42++ == 3`
这可以通过匹配占位符,使用名称作为哈希键,并且只替换替换哈希中是否存在适当的条目来实现:
(my $output = $input) =~
s/\$(\w+)/exists $replacements{$1} ? $replacements{$1} : '$'.$1/eg;
或
(my $output = $input) =~
s/\$(\w+)(?(?{exists $replacements{$1}})|(*F))/$replacements{$1}/g;
这种使用散列的单个替换的策略也保证了字符串的每个部分只被评估一次,并且不会发生双重插值。
如果只需要插入一个占位符,我们可以通过不使用哈希来简化:
s/\$COLOR/red/g;
这有以下缺点:
s///
可以实现双重转义,这通常是一个错误。