我正在开发一个支持多种语言的项目。我们拥有的功能之一是支持替换参数。这是我的意思的简化示例:
字符串“ {CUSTNAME} has 10 customers
”在某处定义。它包括一个参数{CUSTNAME}
,将在使用该字符串的层次结构中定义。当打开带有此字符串的项目时,将{CUSTNAME}
解析为其定义的值。
由于在某些语言中,单个单词或短语实际上可以更改句子中的前面或后面的字符,在这种情况下如何实现替换字段功能?
我正在开发一个支持多种语言的项目。我们拥有的功能之一是支持替换参数。这是我的意思的简化示例:
字符串“ {CUSTNAME} has 10 customers
”在某处定义。它包括一个参数{CUSTNAME}
,将在使用该字符串的层次结构中定义。当打开带有此字符串的项目时,将{CUSTNAME}
解析为其定义的值。
由于在某些语言中,单个单词或短语实际上可以更改句子中的前面或后面的字符,在这种情况下如何实现替换字段功能?
你需要做一些事情。
(1)。设置一些函数,根据该语言的数量和规则返回不同的翻译。
除了您的客户名称替换之外,该部分10 customers
还需要一些替换,并且需要使用看起来更像的函数调用来构建:
ngettext( 'customer', 'customers', 10 )
(2)。设置您的翻译源字符串,使其了解复数规则。
你还没有说你正在使用什么技术,但是 Gettext 有这个内置的,包括PHP在内的许多语言可以与你的系统 Gettext 交互。
(3)。将您的文本替换组织成两个阶段。可能使用 sprintf 代替您的令牌替换,但这部分取决于您。
因为您正在使用存储的翻译以及您自己的客户名称替换,所以我会这样做:
使用每种语言的完整模板设置翻译字符串,在 Gettext PO 文件中可能如下所示:
# ....
msgid "%1$s has one customer"
msgid_plural "%1$s has %2$u customers"
msgstr[0] "%1$s a un client"
msgstr[1] "%2$u clients pour %1$s"
然后,您将根据数量获取所需的模板,然后执行替换。例如在 PHP 中:
$n = 10;
$name = "Pierre";
$template = ngettext( '%1$s has one customer', '%1$s has %2$u customers', $n );
$rendered = sprintf( $template, $name, $n );
这里有很多陷阱,并不是所有的语言包格式都支持复数。如果你不能在你的系统中使用 Gettext,那么看看Loco作为一种管理复数规则并导出为你可以使用的文件格式的方法。