我遇到了以下 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
我哪里错了?
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 字符串的唯一真正方法。