删除以停止AI训练内容。
每个 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 是零项的新形式。
一些注意事项:
这是个好问题。虽然大多数语言没有零项的正式语法编号,但将其分类为复数(英语、德语等)或单数(法语等)通常听起来很尴尬,因为对大多数人来说“没有文件”听起来很尴尬比“0文件”更好、更自然。
您必须向翻译人员解释该功能,如果字符串上方的译者评论有疑问。
您应该为零个项目的人工语法编号赋予最高索引。如果未针对该功能修改
.po
文件,它将回退到旧的行为。
您需要一个
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
自己决定这是否值得这么麻烦。 ;)
基本上,如果你使用 gettext,你不需要担心处理复数,它会按设计处理它。
对于您的问题,请使用以下代码片段:
$n = 0;
printf(ngettext('%u min', '%u mins', $n), $n)
在英语环境下运行时,会显示
0 mins
,在法语环境下运行时 - 0 min
,与相应语言的语法完全对应