具有适当复数的Java国际化(i18n) [英] Java internationalization (i18n) with proper plurals

查看:397
本文介绍了具有适当复数的Java国际化(i18n)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算使用Java的标准i18n系统和复数形式的ChoiceFormat类,但后来意识到它不能处理某些语言的复杂复数规则(例如波兰语)。如果它只处理类似于英语的语言,那么它似乎有点无意义。

I was going to use Java's standard i18n system with the ChoiceFormat class for plurals, but then realized that it doesn't handle the complex plural rules of some languages (e.g. Polish). If it only handles languages that resemble English, then it seems a little pointless.

有哪些选项可以实现正确的复数形式?使用它们有什么利弊?

What options are there to achieve correct plural forms? What are the pros and cons of using them?

推荐答案

嗯,你已经正确标记了这个问题,所以我假设你知道的事情或者两个关于 ICU

Well, you already tagged the question correctly, so I assume you know thing or two about ICU.

使用ICU你正确处理复数形式有两种选择:

With ICU you have two choices for proper handling of plural forms:

  • PluralRules, which gives you the rules for given Locale
  • PluralFormat, which uses aforementioned rules to allow formatting

使用哪一个?就个人而言,我更喜欢直接使用PluralRules,从资源包中选择适当的消息。

Which one to use? Personally, I prefer to use PluralRules directly, to select appropriate message from the resource bundles.

ULocale uLocale = ULocale.forLanguageTag("pl-PL");
ResourceBundle resources = ResourceBundle.getBundle( "path.to.messages",
                               uLocale.toLocale());
PluralRules pluralRules = PluralRules.forLocale(uLocale);

double[] numbers = { 0, 1, 1.5, 2, 2.5, 3, 4, 5, 5.5, 11, 12, 23 };
for (double number : numbers) { 
  String resourceKey = "some.message.plural_form." + pluralRules.select(number);
  String message = "!" + resourceKey + "!";
  try {
    message = resources.getString(resourceKey);
    System.out.println(format(message, uLocale, number));
   } catch (MissingResourceException e) { // Log this } 
}

当然你(或译者)需要在属性文件中添加正确的表格,在这个例子中,我们说:

Of course you (or the translator) would need to add the proper forms to properties file, in this example let's say:

some.message.plural_form.one=Znaleziono {0} plik
some.message.plural_form.few=Znaleziono {0} pliki
some.message.plural_form.many=Znaleziono {0} plików
some.message.plural_form.other=Znaleziono {0} pliku

对于其他语言(即阿拉伯语)你可能还需要使用零和两个关键字,请参阅 CLDR的语言复数有关详细信息的规则

For other languages (i.e. Arabic) you might also need to use "zero" and "two" keywords, see CLDR's language plural rules for details.

您也可以使用PluralFormat选择有效的表单。通常的例子显示直接实例化,在我看来完全没有意义。使用 ICU的MessageFormat :

Alternatively you can use PluralFormat to select valid form. Usual examples show direct instantiation, which totally doesn't make sense in my opinion. It is easier to use it with ICU's MessageFormat:

String pattern = "Znaleziono {0,plural,one{# plik}" +
                 "few{# pliki}" +
                 "many{# plików}" +
                 "other{# pliku}}";
MessageFormat fmt = new MessageFormat(pattern, ULocale.forLanguageTag("pl-PL"));
StringBuffer result = new StringBuffer();
FieldPosition zero = new FieldPosition(0);
double[] theNumber = { number };
fmt.format(theNumber, result, zero);

当然,实际上你不会硬编码模式字符串,但在属性文件中放置这样的东西:

Of course, realistically you would not hardcode th pattern string, but place something like this in the properties file:

some.message.pattern=Found {0,plural,one{# file}other{# files}}

这种方法的唯一问题是,翻译者必须知道占位符格式。我试图在上面的代码中展示的另一个问题是,MessageFormat的静态格式()方法(易于使用的方法)总是为默认的Locale格式化。这可能是Web应用程序中的一个真正问题,其中默认Locale通常表示服务器的一个。因此,我必须格式化特定的Locale(浮点数,请注意),代码看起来相当难看......

The only problem with this approach is, the translator must be aware of the placeholder format. Another issue, which I tried to show in the code above is, MessageFormat's static format() method (the one that is easy to use) always formats for the default Locale. This might be a real problem in web applications, where the default Locale typically means the server's one. Thus I had to format for a specific Locale (floating point numbers, mind you) and the code looks rather ugly...

我仍然更喜欢PluralRules方法,我更清洁(虽然它需要使用相同的消息格式样式,只用辅助方法包装)。

I still prefer the PluralRules approach, which to me is much cleaner (although it needs to use the same message formatting style, only wrapped with helper method).

这篇关于具有适当复数的Java国际化(i18n)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆