在Perl中我应该使用什么而不是printf?

时间:2009-04-17 11:49:08

标签: perl printf string-formatting

我需要在Perl中使用一些字符串替换来简化翻译,即替换许多

print "Outputting " . $n . " numbers";

类似

printf ("Outputting %d numbers", $n);

但是,我想用更容易为人类解析的东西替换printf,如下所示:

printX ("Outputting {num} numbers", { num => $n });

或者更多Perly。

你能推荐一些你喜欢和使用过的东西吗?

8 个答案:

答案 0 :(得分:14)

简单地说:

 print "Outputting $n numbers";

那非常可爱。如果您不需要任何花哨的格式,字符串插值绝对是可行的方法。

答案 1 :(得分:12)

CPAN上的大多数模板模块可能会做你想要的。以下是使用Template Toolkit ...

的示例
use Template;
my $tt = Template->new;

$tt->process( \"Outputting [% num %] numbers\n", { num => 100 } );


你可以用这样的东西模仿你所需的例子......

sub printX {
    use Template;
    my $tt = Template->new( START_TAG => '{', END_TAG => '}' );
    $tt->process( \( $_[0] . "\n" ), $_[1] );
}

你已经......

printX 'Outputting {num} numbers' => { num => 100 };

答案 2 :(得分:5)

print内置对大多数情况非常方便。除了变量插值:

print "Outputting $n numbers";    # These two lines
print "Outputting ${n} numbers";  # are equivalent

请记住print可以使用多个参数,因此如果需要打印子例程调用的结果,则无需先将它们连接成单个字符串:

print "Output data: ", Dumper($data);

但是,对于输出简单整数以外的数字,您可能需要printf的格式化便利性。尽管如此,使用print输出其他数据类型也很容易。

您可以使用join方便地输出数组:

print join ', ', @array;

mapkeys结合输出哈希值:

print join ', ', map {"$_ : $hash{$_}"} keys %hash;

如果要在数据周围输出引号,请使用qq运算符:

print join ', ', map {qq("$_" : "$hash{$_}"}) keys %hash;

答案 3 :(得分:5)

如果您希望简化翻译,则应考虑使用其中一个可用的L10n / i18n CPAN模块。具体来说,很好地概述了您的方法最终会落空的原因written up as part of the Local::Maketext docs

与Locale :: Maketext很好地配对的另一个很棒的模块是Locale::Maketext::Lexicon。这允许您使用更多标准的本地化格式,例如gettext的.po / .mo文件,这些文件具有GUI工具,可帮助翻译人员处理所有需要翻译的文本。 Locale :: Maketext :: Lexicon还附带了一个帮助脚本(xgettext.pl),可帮助您的本地化文件与包含需要翻译的文本的模板或模块保持同步。我过去在这种设置方面取得了非常好的成绩。

答案 4 :(得分:4)

似乎你想要一种不同的解析字符串的方法。我建议你不要这样做。唯一一个看到%d语法的人是开发人员,他将完全理解其含义。 printf语法很强大,因为有填充,小数等选项。

我认为你想要使用更多的替换方法。做s / {num} / $ n /.

是很有意义的

答案 5 :(得分:1)

根据您对翻译人员的评论,我建议您编写一个剥离所有printf()的perl脚本,并以更容易翻译的方式将它们制成表格。

这样的事情:

while(<>)
{
    #regex for striping printf

    #print in tabulated form
}

如果您也打印出行号,您可以轻松编写另一个程序来替换翻译后的文本。

这个解决方案不会比你重新分解printf()并且它可以重复使用。


我肯定会坚持使用printf(),这是许多语言的标准。

它几乎已成为字符串输出的标准。就像i循环一样for

答案 6 :(得分:1)

一般来说Draegtun的答案很棒,但是如果你需要更小的东西(即更少的内存),而不是那么强大,你可以使用这个功能轻松地做到这一点:

sub printX {
    my ( $format, $vars ) = @_;

    my @sorted_keys = sort { length($b) <=> length($a) } keys %{ $vars };
    my $re = join '|', map { "\Q$_\E" } @sorted_keys;

    $format =~ s/ \{ \s* ($re) \s* \} /$vars->{$1}/xg;

    print $format;
}

答案 7 :(得分:-2)

好吧,perl有printf功能...... 等等,你想要python's string formatting with dict之类的东西吗?

 >>> print '%(key)s' % {'key': 'value'}
 value
嗯,我不知道perl中存在类似的东西...... 至少不是这个“容易”...... 也许Text::Sprintf::Named可以成为你的朋友