假设我有一个环境变量 myvar
:
myvar=\tapple\n
当执行以下命令时,将打印出此变量。
perl -e 'print "$ENV{myvar}"'
我有一个字符串
\tapple\n
,但是我希望这些控制字符被执行而不是被转义,请问该如何实现?在实际应用中,
$ENV
通常会被替换,但我希望你的回答能够涵盖这种情况。假设我有一个环境变量 myvar
:
myvar=\tapple\n
perl -e 'print "$ENV{myvar}"'
\tapple\n
,但是我希望这些控制字符被执行而不是被转义,请问该如何实现?$ENV
通常会被替换,但我希望你的回答能够涵盖这种情况。perl -e 'print eval qq{"$ENV{myvar}"}'
更新:您还可以使用带有ee
开关的替换,这样更安全:
perl -e '(my $s = $ENV{myvar}) =~ s/(\\n|\\t)/"qq{$1}"/gee; print $s'
eval
比手动实现更可靠。另一方面,eval
不仅仅是将"\t"转换为Tab字符 - 它还可以删除文件 :) - jrockwayString::Escape
。use String::Escape qw(unbackslash);
my $var = unbackslash($ENV{'myvar'});
unbackslash
可以将任何字符串转义序列解码,使其成为它们所代表的字符。如果你只想显式地转换\n
和\t
,你可能需要自己使用s
ubstitution来实现,例如这个答案。
包含反斜杠\
的字符序列并没有什么特别之处。如果您想要用另一个字符序列替换它,那么在Perl中实现这一点非常简单:
my %sequences = (
'\\t' => "\t",
'\\n' => "\n",
'foo' => 'bar',
);
my $string = '\\tstring fool string\\tfoo\\n';
print "Before: [$string]\n";
$string =~ s/\Q$_/$sequences{$_}/g for ( keys %sequences );
print "After: [$string]\n";
\ 的唯一技巧是要注意 Perl 认为它是转义字符的次数。
Before: [\tstring fool string\tfoo\n]
After: [ string barl string bar
]
然而,正如darch所指出的那样,你可能只需要使用String::Escape。
请注意,在从环境变量中获取值时,你必须非常小心。我不愿意使用String::Escape
,因为它可能会处理比你想要转换的更多内容。安全的方法是仅展开你明确想要允许的特定值。请参阅我的《Perl大师》一书中的“安全编程技术”章节,在其中我谈到了这个问题,以及在这种情况下你可能想要使用的污点检查。