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

时间:2022-03-30 13:46:21

I need to use some string replacement in Perl to ease translations, i.e. replace many

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

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

by something like

通过类似的东西

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

However, I'd like to replace printf with something easier to parse for humans, like this:

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

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

or generally something more Perly.

或者更普遍的东西。

Can you recommend something (from CPAN or not) you like and use?

你能推荐一些你喜欢和使用的东西(无论是否来自CPAN)?

8 个解决方案

#1


Most Templating modules on CPAN will probably do what you want. Here's an example using Template Toolkit...

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

use Template;
my $tt = Template->new;

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


And you can mimic your required example with something like this...

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

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

and you've got...

你有......

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

#2


What about simply:

简单来说:

 print "Outputting $n numbers";

That's very Perly. If you don't need any kind of fancy formatting, string interpolation is definitely the way to go.

那非常Perly。如果你不需要任何类型的花式格式,字符串插值绝对是你要走的路。

#3


The print builtin is very convenient for most situations. Besides variable interpolation:

在大多数情况下,内置打印非常方便。除了变量插值:

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

Remember that print can take multiple arguments, so there is no need to concatenate them first into a single string if you need to print the result of a subroutine call:

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

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

However, for outputting numbers other than simple integers, you'll probably want the formatting convenience of printf. Outputting other data types is easy with print, though.

但是,为了输出除简单整数之外的数字,您可能需要printf的格式化便利性。但是,通过打印输出其他数据类型很容易。

You can use join to conveniently output arrays:

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

print join ', ', @array;

And combine with map and keys to output hashes:

并结合地图和键输出哈希:

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

Use the qq operator if you want to output quotes around the data:

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

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

#4


If you're looking to ease translations you should consider using one of the L10n/i18n CPAN modules that are available. Specifically, a good overview of why your approach will end up falling short is written up as part of the Local::Maketext docs.

如果您希望简化翻译,则应考虑使用可用的L10n / i18n CPAN模块之一。具体来说,很好地概述了为什么你的方法最终会失败,这是作为Local :: Maketext文档的一部分编写的。

Another great module that pairs nicely with Locale::Maketext is Locale::Maketext::Lexicon. This allows you to use more standard localization formats such as gettext's .po/.mo files which have GUI tools to help translators work through all the text that needs translating. Locale::Maketext::Lexicon also comes with a helper script (xgettext.pl) that helps keep your localization files up-to-date with your templates or modules that have text that need translating. I've had very good results with this kind of setup in the past.

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

#5


It seems you want to have a different way of parsing strings. I would advise you not to do this. The only one who is seeing the syntax with the %d in it is the developer and he will exactly understand what is meant. The printf syntax is powerful because of the options like padding, decimals etc.

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

I think you want to use more a replace method. It is perlish to do s/{num}/$n/.

我想你想要使用更多的替换方法。做s / {num} / $ n /是很有意义的。

#6


In light of your comment about being for translators I suggest writing a perl script that strips all printf() and tabulates them in an easier more translator friendly manner.

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

Something like this:

像这样的东西:

while(<>)
{
    #regex for striping printf

    #print in tabulated form
}

If you print out the line number too you can easily write another program to replace the translated text.

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

This solution wouldn't take you any longer than re-factoring away from printf() and it's reusable.

这个解决方案不会花费你的时间来重新分解printf()并且它是可重用的。


I would definitely stick with printf(), it's standard across many languages.

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

It has almost become a standard for string output. Like i is for for loops.

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

#7


Generally answer from Draegtun is great, but if you'd need something smaller (i.e. less memory), and not as powerful you can easily do it using this function:

一般来说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;
}

#8


well, perl has printf function... wait, do you want something like python's string formatting with dict?

好吧,perl有printf函数...等等,你想要像dthon的python的字符串格式吗?

 >>> print '%(key)s' % {'key': 'value'}
 value

mmm, I don't know something like that exist in perl... at least not this "easy"... maybe Text::Sprintf::Named can be your friend

嗯,我不知道perl中存在类似的东西...至少不是这个“简单”......也许Text :: Sprintf :: Named可以成为你的朋友

#1


Most Templating modules on CPAN will probably do what you want. Here's an example using Template Toolkit...

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

use Template;
my $tt = Template->new;

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


And you can mimic your required example with something like this...

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

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

and you've got...

你有......

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

#2


What about simply:

简单来说:

 print "Outputting $n numbers";

That's very Perly. If you don't need any kind of fancy formatting, string interpolation is definitely the way to go.

那非常Perly。如果你不需要任何类型的花式格式,字符串插值绝对是你要走的路。

#3


The print builtin is very convenient for most situations. Besides variable interpolation:

在大多数情况下,内置打印非常方便。除了变量插值:

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

Remember that print can take multiple arguments, so there is no need to concatenate them first into a single string if you need to print the result of a subroutine call:

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

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

However, for outputting numbers other than simple integers, you'll probably want the formatting convenience of printf. Outputting other data types is easy with print, though.

但是,为了输出除简单整数之外的数字,您可能需要printf的格式化便利性。但是,通过打印输出其他数据类型很容易。

You can use join to conveniently output arrays:

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

print join ', ', @array;

And combine with map and keys to output hashes:

并结合地图和键输出哈希:

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

Use the qq operator if you want to output quotes around the data:

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

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

#4


If you're looking to ease translations you should consider using one of the L10n/i18n CPAN modules that are available. Specifically, a good overview of why your approach will end up falling short is written up as part of the Local::Maketext docs.

如果您希望简化翻译,则应考虑使用可用的L10n / i18n CPAN模块之一。具体来说,很好地概述了为什么你的方法最终会失败,这是作为Local :: Maketext文档的一部分编写的。

Another great module that pairs nicely with Locale::Maketext is Locale::Maketext::Lexicon. This allows you to use more standard localization formats such as gettext's .po/.mo files which have GUI tools to help translators work through all the text that needs translating. Locale::Maketext::Lexicon also comes with a helper script (xgettext.pl) that helps keep your localization files up-to-date with your templates or modules that have text that need translating. I've had very good results with this kind of setup in the past.

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

#5


It seems you want to have a different way of parsing strings. I would advise you not to do this. The only one who is seeing the syntax with the %d in it is the developer and he will exactly understand what is meant. The printf syntax is powerful because of the options like padding, decimals etc.

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

I think you want to use more a replace method. It is perlish to do s/{num}/$n/.

我想你想要使用更多的替换方法。做s / {num} / $ n /是很有意义的。

#6


In light of your comment about being for translators I suggest writing a perl script that strips all printf() and tabulates them in an easier more translator friendly manner.

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

Something like this:

像这样的东西:

while(<>)
{
    #regex for striping printf

    #print in tabulated form
}

If you print out the line number too you can easily write another program to replace the translated text.

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

This solution wouldn't take you any longer than re-factoring away from printf() and it's reusable.

这个解决方案不会花费你的时间来重新分解printf()并且它是可重用的。


I would definitely stick with printf(), it's standard across many languages.

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

It has almost become a standard for string output. Like i is for for loops.

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

#7


Generally answer from Draegtun is great, but if you'd need something smaller (i.e. less memory), and not as powerful you can easily do it using this function:

一般来说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;
}

#8


well, perl has printf function... wait, do you want something like python's string formatting with dict?

好吧,perl有printf函数...等等,你想要像dthon的python的字符串格式吗?

 >>> print '%(key)s' % {'key': 'value'}
 value

mmm, I don't know something like that exist in perl... at least not this "easy"... maybe Text::Sprintf::Named can be your friend

嗯,我不知道perl中存在类似的东西...至少不是这个“简单”......也许Text :: Sprintf :: Named可以成为你的朋友