2009-04-17 59 views
7

我需要使用一些字符串替换在Perl来缓解翻译,如更换许多我应该用什么来代替Perl中的printf?

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

通过类似

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

不过,我想的东西容易解析为更换的printf像这样的人类:

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

或通常更多perly。

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

回答

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 }; 
4

看来你想有一个不同的解析字符串的方式。我会建议你不要这样做。唯一一个在其中看到%d的语法的人是开发人员,他完全明白它的含义。由于填充,小数等选项,printf语法功能强大。

我想你想使用更多的替换方法。执行s/{num}/$ n /是完美的。

+1

“唯一的一个是谁看到%d的语法就是开发者“ - >事实并非如此,那些字符串将被翻译者看到,而且非常愚蠢的字符串:)我对printf自己也很好,但我必须考虑其他人... – 2009-04-17 12:02:10

1

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

事情是这样的:

while(<>) 
{ 
    #regex for striping printf 

    #print in tabulated form 
} 

如果打印出来的行号也可以很容易地编写另一个程序来替换翻译文本。

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


我肯定会坚持与printf(),它是许多语言的标准。

它几乎已经成为字符串输出的标准。像i用于for循环。

+0

我使用“循环”:-) – 2009-04-17 12:13:50

+3

与printf的问题是,你也必须得到正确的订单。也就是说,如果一种语言颠倒了被替换的项目的顺序,那么翻译者就是带有一些printf(比如说C)的SOL。为了使翻译更容易,您需要使用“%1 $ d”,以便轻松移动它。模板工具包使这个微不足道。 – Tanktalus 2009-04-17 17:28:34

14

什么简单:

print "Outputting $n numbers"; 

这是非常佩尔利。如果你不需要任何花哨的格式,字符串插值绝对是一种可行的方式。

+0

感谢您的建议,在大多数情况下,我猜这是合适的想法,但我并不总是输出插值变量(Dumper(\%hash))。不得不看看结果如何,但我可能需要一些更灵活的东西...... – 2009-04-17 12:05:16

+3

在插值中输出任意表达式有一个习惯用法:print“Hash is:@ {[Dumper(\%hash)]}”;它不漂亮,但它的工作原理。 – 2009-04-17 12:21:10

5

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

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

记住print可以采取多个参数,所以没有必要首先将它们串联成一个字符串,如果你需要打印一个子程序调用的结果:

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

但是,对于输出简单整数以外的数字,您可能需要printf的格式化便利性。不过,输出其他数据类型很容易。

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

print join ', ', @array; 

而且随着mapkeys相结合,输出哈希:如果你想

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

使用qq运营商输出引号将数据:

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

如果您想要简化翻译,您应该考虑使用可用的L10n/i18n CPAN模块之一。具体而言,您的方法最终会失败的原因概述为written up as part of the Local::Maketext docs

与Locale :: Maketext很好地配对的另一个很好的模块是Locale::Maketext::Lexicon。这使您可以使用更多标准本地化格式,例如带有GUI工具的gettext的.po/.mo文件,以帮助翻译人员处理需要翻译的所有文本。 Locale :: Maketext :: Lexicon还附带了一个帮助程序脚本(xgettext.pl),可帮助您的本地化文件随时更新为需要翻译的文本模板或模块。过去这种设置我已经有了很好的结果。

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; 
} 
相关问题