我的字符串包含如下名称列表: “约翰向金,凯利,李和鲍勃询问新年计划”。列表中的名称数量非常多。 我如何在Java中本地化? 我正在考虑ResourceBundle和MessageFormat。我将如何在MessageFormat中为此编写模式? 有没有更好的方法?
答案 0 :(得分:11)
本地化(内联)列表不仅仅是翻译单词“和”.CLDR处理格式化列表的问题,请查看他们的page on lists。我担心ICU还没有支持,所以你可能需要单独编写代码。
另一个问题是你不能指望能够在这样的句子中使用这样的名字。例如,许多语言要求对象处于倾斜形式。在芬兰语中,您的样本句子将为“JohnkysyiKimiltä,Kellyltä,LeeltäjaBobilta uudenvuoden suunnitelmista。”因此,您可能需要找出并包含不同倾向形式的名称。此外,如果使用的语言没有拉丁字母,您可能需要音译形式的名称(例如,阿拉伯语,约翰是جون)。还有其他问题。在俄语中,对应于“被问”的动词取决于主语的性别(例如,спросила与спросил)。
我知道这听起来很复杂,但本地化往往很复杂。如果你只针对一组有限的语言,事情就会容易得多,所以定义你的目标很重要 - 也许接受一些可能导致语法错误表达的简化。但是对于涵盖广泛语言的本地化,您可能需要使生成函数本地化。也就是说,对于每种语言,您将拥有一个函数,该函数接受名称列表作为参数并返回表示该语句的字符串,可能使用包含有关可能名称的信息的资源文件(音译形式,不同的倾斜形式,性别)。出现。
在某些情况下,您甚至可以考虑用英语生成句子,然后将其发送给在线翻译。例如,谷歌翻译可以处理我提到的一些问题。它肯定会产生错误的翻译,但对于语法结构非常简单的句子,如果你能接受一些错误,它可能是一个实用的解决方案。如果您考虑尝试这一点,请确保您充分测试自动翻译器如何处理您将使用的特定句子。通常,您可以通过重新构造句子来改善结果。将具有多个条款的句子分成单独的句子通常会有所帮助。但即使是简单的句子也会导致自动翻译出现问题。
如果您可以重新构建句子结构,例如,您可以避免一些并发症。因此,所有的名词都出现在主题位置,你避免像“新年计划”这样的“包装”表达。例如,“约翰问金,凯利,李和鲍勃在新的一年里有什么计划”会更简单,用于自动翻译和基于模式的本地化。
答案 1 :(得分:3)
您可以执行以下操作:
"{0} asked {1} about the new year plans"
其中0是第一个名称,1是逗号分隔的其他名称列表。
希望这有帮助。
答案 2 :(得分:2)
我看到答案已经被接受了,我只是在这里添加它作为替代方案。代码具有数据的硬编码值,但仅用于提出可以改进的想法:
MessageFormat people = new MessageFormat("{0} asked {1,choice,0#no one|1#{2}|2#{2} and {3}|2<{2}, and {3}} about the new year plans");
String john = "John";
Object[][] parties = new Object[][] { {john, 0}, {john, 1, "Kim"}, {john, 2, "Kim", "Kelly}, {john, 4, "Kim, Kelly, Lee", "Bob"}};
for (final Object[] strings : parties) {
System.out.println(people.format(strings));
}
这输出以下内容:
John asked no one about the new year plans
John asked Kim about the new year plans
John asked Kim and Kelly about the new year plans
John asked Kim, Kelly, Lee, and Bob about the new year plans
确定用于第二个参数的名称数量并为第三个参数创建逗号分隔的字符串不会显示在该示例中,但可以轻松完成,而不是使用我使用的硬编码值。 / p>
答案 3 :(得分:1)
对于本地化,通常的方法是使用外部语言包,该文件包含您要显示的文本,为每个文本分配名称/密钥,然后通过密钥加载程序中的文本。 / p>
答案 4 :(得分:0)
您可以将您的ResourceBundle(对于I18N)与MessageFormat(用名称替换占位符)结合起来:“{0}询问{1}新年计划”
但是,您可以事先准备好名字。