のICUプロジェクト(現在ではPHPライブラリ) には、検索時に値を比較しやすくするために UTF-8 文字列を正規化するために必要なクラスが含まれています。
しかし、私は理解しようとしているこれが何を意味するかアプリケーションの場合。たとえば、「互換性同等性」ではなく「標準同等性」が必要なのはどのような場合ですか。またはその逆ですか。
ベストアンサー1
Unicode 正規化について知りたくなかったことすべて
正規正規化
Unicode には、一部の文字、特にアクセント付き文字をエンコードする複数の方法が含まれています。正規正規化により、コード ポイントが正規のエンコード形式に変更されます。結果のコード ポイントは、フォントやレンダリング エンジンにバグがない限り、元のコード ポイントと同一になります。
使用する場合
結果は同一に見えるため、結果が入力とビット単位で同一でなくても許容できる限り、文字列を保存または表示する前に、文字列に正規正規化を適用するのが常に安全です。
正規正規化には、NFD と NFC の 2 つの形式があります。これら 2 つの形式は、損失なく変換できるという意味で同等です。NFC で 2 つの文字列を比較すると、NFD で比較した場合と常に同じ結果になります。
NFD
NFD では文字が完全に拡張されます。これは計算が高速な正規化形式ですが、結果としてコード ポイントが多くなります (つまり、より多くのスペースが使用されます)。
まだ正規化されていない 2 つの文字列を比較するだけの場合は、互換性正規化が必要であることがわかっている場合を除き、これが推奨される正規化形式です。
非対称
NFC は、NFD アルゴリズムを実行した後、可能な場合はコード ポイントを再結合します。これには少し時間がかかりますが、文字列は短くなります。
互換性の正規化
Unicode には、実際には属さないが、従来の文字セットで使用されていた文字も多数含まれています。Unicode では、これらの文字セットのテキストを Unicode として処理し、損失なく元の文字セットに戻すことができるように、これらの文字が追加されました。
互換性正規化では、これらを対応する「実際の」文字のシーケンスに変換し、標準正規化も実行します。互換性正規化の結果は、元の文字と同一ではない場合があります。
書式設定情報を含む文字は、含まない文字に置き換えられます。たとえば、文字⁹
は に変換されます9
。その他の文字には書式設定の違いはありません。たとえば、ローマ数字文字Ⅸ
は通常の文字 に変換されますIX
。
当然ながら、この変換を実行すると、元の文字セットにロスレスで戻すことはできなくなります。
いつ使うか
Unicode コンソーシアムは、互換性正規化をToUpperCase
変換のように考えることを提案しています。これは状況によっては役立つかもしれませんが、むやみに適用すべきではありません。
優れた使用例は検索エンジンです。おそらく、 の検索が と9
一致することが必要になるでしょう⁹
。
おそらく行うべきではないことの 1 つは、互換性正規化を適用した結果をユーザーに表示することです。
NFKC/NFKD
互換性正規化形式には、NFKD と NFKC の 2 つの形式があります。これらは、NFD と C の関係と同じです。
NFKC 内の任意の文字列は本質的に NFC 内にもあり、NFKD と NFD についても同様です。したがってNFKD(x)=NFD(NFKC(x))
、、、NFKC(x)=NFC(NFKD(x))
などです。
結論
疑問がある場合は、正規正規化を使用してください。適用可能なスペースと速度のトレードオフに基づいて、または相互運用するものに必要なものに基づいて、NFC または NFD を選択します。