38

Java の標準 i18n システムを複数形の ChoiceFormat クラスとともに使用するつもりでしたが、一部の言語 (ポーランド語など) の複雑な複数形ルールを処理できないことに気付きました。英語に似た言語しか扱っていないのでは、ちょっともったいないですよね。

正しい複数形を実現するには、どのようなオプションがありますか? それらを使用することの長所と短所は何ですか?

4

2 に答える 2

45

さて、あなたはすでに質問に正しくタグを付けているので、 ICUについて 1 つまたは 2 つのことを知っていると思います。

ICU では、複数形を適切に処理するための 2 つの選択肢があります。

  • 指定された Locale のルールを提供するPluralRules
  • PluralFormat、前述のルールを使用してフォーマットを許可します

どちらを使用しますか?個人的には、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

他の言語 (アラビア語など) の場合は、"zero" および "two" キーワードを使用する必要がある場合もあります。詳細については、 CLDR の言語の複数形規則を参照してください。

または、PluralFormat を使用して有効なフォームを選択することもできます。通常の例は直接インスタンス化を示していますが、これは私の意見ではまったく意味がありません。ICU の 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);

もちろん、現実的には、パターン文字列をハードコードするのではなく、プロパティ ファイルに次のようなものを配置します。

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

このアプローチの唯一の問題は、翻訳者がプレースホルダー形式を認識している必要があることです。上記のコードで示そうとしたもう 1 つの問題は、MessageFormat の static format() メソッド (使いやすいメソッド) が常にデフォルトの Locale 用にフォーマットされることです。これは、デフォルトの Locale が通常サーバーの Locale を意味する Web アプリケーションでは、実際の問題になる可能性があります。したがって、特定のロケール(浮動小数点数、気をつけてください)用にフォーマットする必要があり、コードはかなり見苦しく見えます...

私はまだ PluralRules アプローチを好みます。これは、私にとってははるかにクリーンです (ただし、同じメッセージ形式のスタイルを使用する必要があり、ヘルパー メソッドでラップするだけです)。

于 2013-01-14T22:10:20.933 に答える
3

ChoiceFormatここで説明したように、あなたが投げる可能性のあるあらゆる種類の複数形に対処するのに十分な柔軟性があるようです.

編集: Haribo 博士がコメントで指摘したように、ChoiceFormat はポーランド語の複数形には不十分です。しかし、同じブログからのフォローアップは、より複雑な複数形規則を処理する ICU4J を示唆しています。

于 2013-01-14T21:21:43.290 に答える