有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

具有适当复数的Java国际化(i18n)

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

有哪些选项可以实现正确的复数形式?使用它们的优缺点是什么


共 (2) 个答案

  1. # 1 楼答案

    好吧,你已经正确地标记了这个问题,所以我想你知道关于ICU的一两件事

    在ICU中,正确处理复数形式有两种选择:

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

    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 } 
    }
    

    当然,您(或翻译人员)需要将适当的表单添加到属性文件中,在本例中,假设:

    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's language plural rules

    或者,您可以使用PluralFormat选择有效的表单。通常的例子显示直接实例化,这在我看来完全没有意义。与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);
    

    当然,实际上您不会硬编码th模式字符串,而是在属性文件中放置如下内容:

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

    这种方法唯一的问题是,译者必须知道占位符的格式。我试图在上面的代码中说明的另一个问题是,MessageFormat的static format()方法(易于使用的方法)总是为默认语言环境设置格式。这在web应用程序中可能是一个真正的问题,默认语言环境通常意味着服务器的语言环境。因此,我必须为特定的语言环境(请注意,浮点数字)设置格式,代码看起来相当难看

    我仍然更喜欢PluralRules方法,它对我来说更干净(尽管它需要使用相同的消息格式样式,只使用helper方法包装)

  2. # 2 楼答案

    ChoiceFormat,因为explained here似乎足够灵活,可以处理你可能抛出的任何形式的多元化

    编辑:正如哈里博博士在评论中指出的,ChoiceFormat不足以实现波兰的多元化。但a followup from the same blog建议ICU4J处理更复杂的多元化规则