在 Perl 中我应该使用什么来代替 printf ?

发布于 2024-07-16 16:13:01 字数 371 浏览 6 评论 0原文

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

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

类似的东西替换许多字符串

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

但是,我想用更易于人类解析的东西替换 printf,就像这样:

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

或者通常更 Perly 的东西。

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

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

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:

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

or generally something more Perly.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

兲鉂ぱ嘚淚 2024-07-23 16:13:01

简单地说:

 print "Outputting $n numbers";

这非常Perly。 如果您不需要任何花哨的格式,那么字符串插值绝对是最佳选择。

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.

可是我不能没有你 2024-07-23 16:13:01

CPAN 上的大多数模板模块可能会满足您的需求。 以下是使用模板工具包的示例...

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

Most Templating modules on CPAN will probably do what you want. Here's an example using 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 };
唯憾梦倾城 2024-07-23 16:13:01

内置的 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;

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 "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.

You can use join to conveniently output arrays:

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:

print join ', ', map {qq("$_" : "$hash{$_}"}) keys %hash;
往事随风而去 2024-07-23 16:13:01

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

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

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.

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.

裂开嘴轻声笑有多痛 2024-07-23 16:13:01

看来你想要一种不同的方式来解析字符串。 我建议你不要这样做。 唯一看到其中包含 %d 的语法的是开发人员,他会准确理解其含义。 printf 语法非常强大,因为它有填充、小数等选项。

我认为你想更多地使用替换方法。 这样做是很危险的 s/{num}/$n/。

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.

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

雅心素梦 2024-07-23 16:13:01

根据您关于翻译人员的评论,我建议编写一个 perl 脚本,该脚本删除所有 printf() 并以更简单、更翻译人员友好的方式将它们制成表格。

像这样的事情:

while(<>)
{
    #regex for striping printf

    #print in tabulated form
}

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

该解决方案不会花费您比从 printf() 进行重构更长的时间,而且它是可重用的。


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

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

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.

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.


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

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

梦年海沫深 2024-07-23 16:13:01

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

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:

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;
}
仙女 2024-07-23 16:13:01

好吧,perl 有 printf 函数...
等等,你想要像 python 的 dict 字符串格式化之类的东西吗?

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

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

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

 >>> 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文