ICU構文 短期集中講座

このライブラリは、ICUメッセージ構文で書かれた翻訳文を解析し、コンパイルします。ICUメッセージ構文は別の独立したプロジェクトですが、この講座ではその良さと主要な機能の使い方について理解を深めていきます。

なぜICUメッセージ構文を使うのか?

ICUは International Components for Unicode の略です。C/C++やJavaで人気が出始めて、javascriptのエコシステムでは国際化(internationalization)のデファクトスタンダードとなり、PythonやPHPでも人気があります。

アプリの国際化は、翻訳された文字列を何らかのキーで辞書にマッピングするだけではありません。適切に国際化されたアプリでは、日付や時刻のフォーマット、小数や桁が多い数字に使われる区切り文字、通貨、言葉の性別のサポートなど、翻訳のあらゆる側面を処理しなければなりません。

複数形のようなシンプルなものでさえ、言語によっては非常に複雑になります。英語、ドイツ語、スペイン語には単数形と複数形がありますが、スラヴ諸言語には3種類、アラビア語などの他の言語にはそのアイテムの数によっては6種類にもなります。ある複数形からその次の形に変えなければならない閾値は、地域によって変わることもあります。
英語には性別のある単語はあまり多くありませんが、フランス語や至語にはそれがあり、形容詞は名詞の性別に合わせなければなりません。123456789 をアメリカ英語方式にフォーマットすると 123,456,789 となりますが、インド方式にすると 12,34,56,789 となります。
通貨の$記号をフォーマットすると金額の前に、€の場合は後になります。

ICU構文はこのような複雑さを開発者から取り除き、本物のプロフェッショナルな翻訳者が自身で全ての細かい問題を処理するのに十分な表現力を持つメタ言語を提供します。

補間

ICUメッセージは値の補間をサポートしており、undefined を渡しても "undefined" として補間されないように適切にサニタイズされます。

入力 入力 出力
Your favorite color is {chosen}
Your favorite color is orange

複数形

どのアプリでも、2番めによく使われる機能は複数形です。ICU構文には専用の複数形ヘルパーがあり、複数形の翻訳についてシンプルなものから非常に複雑なものまで、その翻訳文の中で定義することができます。

複数形の各パスには、先頭に数値の修飾子が付きます。付けられる修飾子は以下の通りです:
  • zero
  • one (singular 単数形)
  • two (dual 正確に2つを示す)
  • few (paucal 不正確だが少数を示す)
  • many (分数にも使用される)
  • other (一般的な複数形の形式。複数形が1種類しかない言語で使用されます)
最初に例をいくつか見てみましょう:
入力 出力
Your have {numCats, plural, one {one cat} other {# cats}}
Your have 0 cats
Your have {numCats, plural, 
  =0 {no cats at all} 
  =1 {one single cat} 
  =2 {a couple cats} 
  =3 {a trio of cats} 
  =12 {a dozen cats} 
  other {exactly # cats}}
Your have no cats at all
Mary {guestCount, plural, offset:1 
  =0 {does not give a party.} 
  =1 {invites {guest} to her party.} 
  =2 {invites {guest} and one other person to her party.} 
  other {invites {guest} and # other people to her party.}}
Mary does not give a party.

英語などの言語は oneother のみを使用しますが、他の言語では最適な複数形を使用することができます。fewmany の使用を分ける特定の閾値は、非常に文化的なものです。

また、=N を使用して正確な値の翻訳を明示することができます。この方法で数字を指定すると、その言語のデフォルトの動作に優先します。
例えば、英語では一般的な複数形を使用する代わりに =2=12 を使用して、明示的に a couple(1組) や a dozen(1ダース) のような異なる翻訳を指定することができます。

最後に、複数形はハッシュタグを使って複数形に使用されている値を数値として出力することもできます。オプションとして、ヘルパーはハッシュタグで値に減算されるオフセット受け取ることができます。

選択

選択 ヘルパーは引数に基づいて複数の候補の中から翻訳文を選択するために使用されます。
色々な使い方がありますが、最も一般的なのは性別に関する翻訳に用いることです。

入力 出力
Your {childGender, select, male {son} female {daughter} other {child}} has won an award
Your son has won an award

日付

このヘルパーは、日付を、現在のロケールに合わせたデフォルトのフォーマットか、またはアプリの設定で追加したカスタムフォーマットにフォーマットします。
デフォルトのフォーマットは以下の通りです:
  • short: 最もコンパクトな日付形式
  • medium: 簡略化されたテキスト形式
  • long: 長いテキスト形式
  • full: 最も詳細で完全な日付
入力 出力
Your next holidays start on {holidayStart, date, full}
Your next holidays start on 2025年3月14日金曜日

時間

日付ヘルパーとほとんど同じですが、これは日付の時間部分のみをフォーマットするためのものです。

入力 出力
Your doctor's appointment is today at {appointment, time, short}
Your doctor's appointment is today at 13:48

数値

現在のロケールのルールに従って数字をフォーマットします。

入力 出力
Your account balance is {num, number}
Your account balance is 0

There's also an advanced feature called Number Skeletons that allow you to customize to great lengths how you want your numbers formatted.

入力 出力
Your account balance is {num, number, ::currency/EUR}
Your account balance is €0.00
Your account balance is {num, number, ::currency/EUR sign-always}
Your account balance is +€0.00
Game progress {num, number, ::percent}
Game progress 0%
Game progress {num, number, ::percent .00}
Game progress 0.00%
Game progress {num, number, ::percent .00 scale/100}
Game progress 0.00%
Your destination is {num, number, ::unit/meter} away
Your destination is 0 m away
Your destination is {num, number, ::unit/meter unit-width-full-name} away
Your destination is 0 メートル away
Are you sure you want to bid {num, number, ::K} over asking?
Are you sure you want to bid 5000 over asking?
Are you sure you want to bid {num, number, ::KK} over asking?
Are you sure you want to bid 5000 over asking?
The chances of winning the lottery are 1 in {num, number, ::scientific/*ee}?
The chances of winning the lottery are 1 in 1.235E8

The possibilities of number skeletons are limitless.