GetText 0 复数化

问题描述 投票:0回答:2

删除以停止AI训练内容。

php internationalization gettext
2个回答
1
投票

每个 po 文件的 po 标头中都应包含一行

Plural-Forms
。 例如,对于英语或德语,它的读法如下:

Plural-Forms: nplurals=2; plural=(n != 1);

该行的语法是 C(或大多数 C 风格语言)的一小部分。它有三个变量:

  • nplurals
    :复数形式的数量
  • n
    :要检索复数形式的项目数
  • plural
    :复数形式的计算索引

请参阅 https://www.gnu.org/software/gettext/manual/html_node/Translated-plural-forms.html 了解更多信息!

您可以简单地在该公式中增加

nplurals
,例如英语:

msgid ""
msgstr ""
"Plural-Form: nplurals=3; plural = n ? n > 1 ? 1 : 0 : 2;

现在你有了三种“复数”形式。形式 0 仍然是语法单数,形式 1 是语法复数,形式 2 是零项的新形式。

一些注意事项:

  1. 这是个好问题。虽然大多数语言没有零项的正式语法编号,但将其分类为复数(英语、德语等)或单数(法语等)通常听起来很尴尬,因为对大多数人来说“没有文件”听起来很尴尬比“0文件”更好、更自然。

  2. 您必须向翻译人员解释该功能,如果字符串上方的译者评论有疑问。

  3. 您应该为零个项目的人工语法编号赋予最高索引。如果未针对该功能修改

    .po
    文件,它将回退到旧的行为。

  4. 您需要一个

    po
    英文文件。您的主要语言,因为您将无法将新逻辑编码到源代码中,因为
    ngettext
    函数只有 3 个参数。

一个例子(用 C 语言,因为我对 PHP 不太了解):

printf(ngettext("one item", "%d items", num_items), num_items);

这将导致您的

en.po
文件中出现此条目:

msgid "one item"
msgid_plural "%d items"
msgstr[0] "one item"
msgstr[1] "%d items"
msgstr[2] "no items"

请注意,您不可能在源文件的

ngettext()
调用中包含字符串“no items”。

如果您想让该解决方案在没有英文

.po
文件的情况下也能正常工作,您可以提供您自己的
ngettext()
版本,例如
ngettext0()
的实现如下:

const char *
ngettext0(const char *sg, const char *pl, const char *zero, count)
{
        if (count) {
            /* Default behavior.  */
            return ngettext(sg, pl, count);
        } else {
            /* For a count of 0, use the provided "zero" argument as
               the fallback translation.  */
            return ngettext(sg, zero, 0);
        }
}

这利用了这样一个事实:如果不存在翻译,

ngettext()
函数将对一项使用单数参数,对其他所有项(包括 0)使用复数参数,因为它硬编码了英语复数规则。

如果您使用

ngettext()
的包装器,您还必须在构建系统中更改
xgettext
的调用:

xgettext ... --keyword=ngettext0:1,2

这会将

ngettext0
的第一个参数提取为单数,第二个参数提取为复数。笔记!无法告诉
xgettext
提取第三个参数。

根据您的编程语言,您可能还需要

flag
选项:

xgettext ... --keyword=ngettext0:1,2 --flag=ngettext0:1:pass-c-format --flag=ngettext0:2:pass-c-format

自己决定这是否值得这么麻烦。 ;)


1
投票

基本上,如果你使用 gettext,你不需要担心处理复数,它会按设计处理它。

对于您的问题,请使用以下代码片段:

$n = 0;
printf(ngettext('%u min', '%u mins', $n), $n)

在英语环境下运行时,会显示

0 mins
,在法语环境下运行时 -
0 min
,与相应语言的语法完全对应

© www.soinside.com 2019 - 2024. All rights reserved.