单复数词的本地化——语法数的不同语言规则是什么?
本文关键字:规则 语言 是什么 本地化 语法 单复数 | 更新日期: 2023-09-27 18:06:19
我一直在开发一个。net字符串格式化库来帮助应用程序的本地化。它叫做SmartFormat,在GitHub上是开源的。
它试图解决的问题之一是语法数。这也被称为"单复数形式"或"条件格式",下面是它的英文片段:
var message = "There {0:is|are} {0} {0:item|items} remaining";
// You can use the Smart.Format method just like using String.Format:
var output = Smart.Format(CultureInfo.CurrentUICulture, message, items.Count);
我相信你知道,英语规则是名词、动词和形容词有两种形式(单数和复数)。如果数量是1
,则使用单数,否则使用复数。
我现在正试图通过为其他语言实现正确的规则来"拓宽我的视野"!我开始明白,有些语言可以有多达4种复数形式,并且需要一些逻辑来确定正确的形式。我想扩展我的代码以适应多种语言。例如,我听说俄语、波兰语和土耳其语的规则与英语完全不同,所以这可能是一个很好的起点。
然而,我只会说英语和西班牙语,那么我如何确定许多常见语言的正确语法规则呢?
Edit:我还想知道一些很好的非英语"测试短语"用于我的单元测试:有哪些很好的非英语短语,可以用单数和复数形式来测试国际化和本地化库?
当然,不同的语言有不同的复数规则。特别有趣的可能是阿拉伯语和波兰语,这两种语言都包含相当多的复数形式。
如果你想了解更多关于这些规则,请访问Unicode通用语言环境数据存储库,即语言复数规则。
那里有相当多有趣的信息,不幸的是其中一些不幸是错误的。我希望复数形式是正确的(至少对波兰语来说是正确的,据我所知:))。
如果你在问题正文中提供你正在使用的规则样本,它们采用什么格式,那就太好了?
不管怎样,在你的例子中:
var message = "There {0:is:are} {0} {0:item:items} remaining";
你似乎是基于这样的假设,即两个选择片段中的选择都基于同一个单一规则,并且这两个选择之间存在直接对应关系——即相同的单一规则会选择(is,item)或(are,items)。
这个假设对于其他语言来说不一定是正确的,例如虚构的语言English-ez(只是为了让读者更容易理解,我发现外语中的例子令人恼火——我借用了阿拉伯语,但简化了很多)。该语言的规则如下:
第一个选择段与正常英语相同:
is: count=1
are: count=0, count=2..infinity
第二个选择段与正常英语的规则不同,假设以下简单规则:
item: count=1
item-da: count=2 # this language has a special dual form.
items: count=0, count=3..infinity
现在单规则解决方案是不够的-我们可以建议一个不同的形式:
var message = "There {0:is:are@rule1} {0} {0:item:items@rule2} remaining";
此解决方案在其他情况下可能存在问题,但我们正在讨论您提供的示例。
检查gettext(允许将完整消息选择到单个级别)和ICU(允许将完整消息选择到多个级别,即多个变量)
您所采取的方法可能对英语和西班牙语的大多数情况有效,但对许多其他语言很可能无效。问题是,你只有一个模式,试图解决所有合乎语法的数字。
var message = "There {0:is|are} {0} {0:item|items} remaining";
每个语法性别都需要一个模式。这里我将两个模式组合成一个单一的多模式字符串。
var message = PluralFormat("one;There is {0} item remaining;other;There are {0} items remaining", count);
英语使用两种语法数:单数和复数。一个开始单数模式,另一个开始复数模式。
例如,当翻译成芬兰语使用相同数量的语法数字时,你会使用
"one;{0} kappale jäljellä;other;{0} kappaletta jäljellä"
然而,日本人只使用一个语法数,所以日本人只使用其他。波兰语使用三个语法数字,所以它包含one, few和many。
其次,您需要适当的规则来选择正确的模式或多个模式。Unicode联盟的CLDR包含XML文件中的规则。
我已经实现了一个开源库,它使用CLDR规则(从XML转换为c#代码并包含在库中)和多模式字符串来支持语法数字和语法性别。
https://github.com/jaska45/I18N使用此库,您的示例将变成
var message = MultiPattern.Format("one;There is {0} item remaining;other;There are {0} items remaining", count);