7

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

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

通过类似的东西

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

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

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

或者通常更珀利。

你能推荐一些你喜欢和使用的东西(来自或不是来自 CPAN)吗?

4

8 回答 8

14

简单地说:

 print "Outputting $n numbers";

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

于 2009-04-17T12:00:56.857 回答
12

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 };
于 2009-04-17T12:42:21.673 回答
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;
于 2009-04-17T16:17:29.130 回答
5

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

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

于 2009-04-17T16:38:34.163 回答
4

看来您希望有一种不同的方式来解析字符串。我建议你不要这样做。唯一看到 %d 语法的人是开发人员,他会完全理解其含义。由于填充、小数等选项,printf 语法非常强大。

我认为您想使用更多的替换方法。做 s/{num}/$n/ 是没用的。

于 2009-04-17T11:53:58.187 回答
1

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

像这样的东西:

while(<>)
{
    #regex for striping printf

    #print in tabulated form
}

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

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


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

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

于 2009-04-17T11:59:09.873 回答
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;
}
于 2009-04-17T17:22:30.657 回答
-2

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

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

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

于 2009-04-17T12:01:25.670 回答