我遇到以下perl问题。拿这段代码把它放到test.pl
中my $str=shift;
printf "$str", @ARGV;
然后像这样运行:
perl test.pl "x\tx%s\n%s" one two three
我的预期输出应为:
x xone
two
相反,我得到了
x\sxone\ntwo
我哪里错了?
答案 0 :(得分:8)
Perl在编译时转换字符串中的转义序列,因此一旦程序运行,您就太迟了,无法将"\t"
和"\n"
转换为制表符和换行符。
使用eval
可以解决这个问题,但这是非常不安全的。我建议您使用String::Interpolate
模块在编译后处理字符串。它使用Perl的原生插值引擎,因此具有与将字符串编码到程序中完全相同的效果。
您的test.pl
变为
use strict;
use warnings;
use String::Interpolate qw/ interpolate /;
my $str = shift;
printf interpolate($str), @ARGV;
<强>输出强>
E:\Perl\source>perl test.pl "x\tx%s\n%s" one two three
x xone
two
E:\Perl\source>
<强>更新强>
如果您只想允许String::Interpolate
支持的一小部分可能性,那么您可以写一些明确的内容,例如
use strict;
use warnings;
my $str = shift;
$str =~ s/\\t/\t/g;
$str =~ s/\\n/\n/g;
printf $str, @ARGV;
但是模块或eval
是在命令行上支持常规Perl字符串的唯一真正方法。