ICU (International Components for Unicode)

Unicode の国際化ライブラリ。文字列の照合・変換・書式設定など多言語処理の基盤を提供する。

ICU (International Components for Unicode) は、Unicode コンソーシアムが開発・保守する国際化 (i18n) ライブラリです。C/C++ 版 (ICU4C) と Java 版 (ICU4J) が提供されており、OS やブラウザ、プログラミング言語のランタイムなど、多くのプラットフォームの多言語処理基盤として採用されています。Android、iOS、macOS、Windows、Chrome、Firefox など、日常的に使われるソフトウェアの内部で ICU が動作しています。

ICU が提供する機能は多岐にわたります。文字列の照合 (ロケール対応のソート) では、言語ごとに異なるアルファベット順序を正確に処理します。たとえばスウェーデン語では「ö」が「z」の後に来ますが、ドイツ語では「o」の変種として扱われます。日付・数値・通貨の書式設定では、「2025/01/15」を英語圏では「January 15, 2025」、ドイツ語圏では「15. Januar 2025」と表示するような変換を行います。

テキスト境界検出 (BreakIterator) は、文字数カウントと特に関連の深い機能です。単語の区切り、文の区切り、行の折り返し位置を言語に応じて正確に判定します。日本語や中国語のようにスペースで単語を区切らない言語では、辞書ベースの解析が必要であり、ICU はこの処理を内部で行っています。JavaScript の Intl.Segmenter API は ICU のテキスト境界検出機能を Web に公開したものです。

ただし単語分割の結果は辞書に依存するため、日本語の単語数カウントを ICU に任せる場合は結果を確認しておく必要があります。「東京都に住んでいます」を単語単位で分割すると「東京 / 都 / に / 住 / んで / い / ます」となり、人間の語感とは異なる区切りが混じります。単語数を仕様として提示するツールを作るなら、この分割規則をそのまま採用するのか、形態素解析器を別に用意するのかを最初に決めておくべきです。

Node.js は v13 以降、ICU のフルデータセットをデフォルトで同梱しており、Intl API の内部実装に ICU が使われています。それ以前のバージョンでは ICU データが部分的にしか含まれず、一部のロケールで正しく動作しない問題がありました。ブラウザでも Intl.CollatorIntl.DateTimeFormatIntl.NumberFormat などの API が ICU を基盤としています。

ICU の照合アルゴリズム (UCA: Unicode Collation Algorithm) は、ロケールごとに異なるソート順序を多段階の比較レベルで処理します。第 1 レベルは基本文字の比較、第 2 レベルはアクセント記号の比較、第 3 レベルは大文字・小文字の比較という階層構造になっています。この仕組みにより、「cafe」と「café」を同一視するか区別するかをアプリケーションの要件に応じて制御できます。JavaScript では Intl.Collatorsensitivity オプションが対応し、base なら両者は等しい (比較結果 0) と判定され、variant なら別の語として順序がつきます。検索の一致判定には緩いレベル、一覧の並び順には厳しいレベル、と使い分けるのが定石です。

文字数カウントとの関連では、ICU の書記素クラスタ (grapheme cluster) 分割機能が重要です。絵文字の家族シーケンス (👨‍👩‍👧‍👦) や結合文字を含むテキストで「ユーザーが認識する 1 文字」を正確にカウントするには、ICU のような高度なテキスト処理ライブラリが不可欠です。単純なコードポイント数やバイト数では正確な文字数を得られない場面で、ICU の機能が真価を発揮します。実際に家族の絵文字 1 個を数えると、書記素クラスタでは 1、コードポイントでは 7、JavaScript の length (UTF-16 単位) では 11 という三通りの値が出ます。どの数え方を採るかは仕様の選択であり、ライブラリの優劣ではありません。

ICU を使う際の実務上の注意点は 2 つあります。1 つは、ICU データを削ったビルドが存在することです。実行環境が英語相当のデータしか持たない場合、指定したロケールは最も近い利用可能なロケールへ黙って読み替えられ、エラーを出さずに並び順や書式だけが変わります。もう 1 つは、ICU と、その参照するロケールデータは更新されるという点です。書式化された文字列そのものを期待値に固定した自動テストは、実行環境の ICU バージョンが違うだけで失敗します。テストでは書式結果を直接比較せず、比較結果の符号や分割数といった安定した性質を検証するほうが堅牢です。

この記事を共有