2009-04-17 94 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; 
} 
相關問題