正規化と並べ替え
一部の Unicode 文字は、一連の Unicode 文字を組み合わせたり合成したりすることによって、複数のバイナリ形式で表現できます。 このため、2 つの文字列が同一に見えても、実際には異なる文字から構成されている場合があります。 1 つの文字に対して複数の表現が存在すると、並べ替え操作が複雑になります。 この問題を解決するには、各文字列を正規化してから、序数の比較を使用して文字列を並べ替えます。
Unicode 規格では、正規化と呼ばれる処理が定義されています。正規化では、ある文字の任意のバイナリ表現を渡すと、その表現に等価な特定の 1 つのバイナリ表現が返されます。 Unicode 規格では、文字列の正規化に使用できる、正規化形式と呼ばれる 4 つの異なるアルゴリズムが定義されています。 各正規化形式は異なる規則に従うため、1 つの入力文字列に対して異なるバイナリ表現を生成します。 ただし、2 つの文字列が同じ正規化形式に正規化された場合、これらの文字列は次に序数の比較 (大文字と小文字を区別しない) を使用して比較できます。
2 つの文字列の序数の比較では、正規化された文字列を表す 2 つの String オブジェクト内にある、Char 構造体の対応する各ぺアの数値 (コード ポイント) をバイナリ比較します。 .NET Framework には、序数の比較を実行できる複数のメソッドが用意されています。
アプリケーションでは、次の手順に従って文字列の正規化および並べ替えを実行できます。
ファイルまたはユーザー入力などの入力ソースから、並べ替える 2 つの文字列を取得します。
String.Normalize() メソッドを使用して、両方の文字列を正規化形式 C に正規化するか、または String.Normalize(NormalizationForm) メソッドを使用して、両方の文字列を選択した正規化形式に正規化します。
序数による文字列比較 (Ordinal 値または OrdinalIgnoreCase 値を使用した Compare(String, Int32, String, Int32, Int32, StringComparison) メソッドなど) を使用して、2 つの文字列を比較します。 この比較操作は、最初の文字列が 2 番目の文字列より構文的に前になるかどうか、または 2 つの文字列が構文的に等しいかどうかを判断します。
手順 3. の結果に基づいて、並べ替え後の出力で文字列を出力します。 文字列が等しくない場合は、昇順または降順で文字列を出力します。
文字列が等しい場合は、構文的な順序以外の特性に基づいて文字列を配置するのが適切である場合を除き、いずれかの文字列を最初に出力します。 たとえば、アプリケーションがファイル名を並べ替えると同時に各ファイルのプロパティも出力に書き込む場合、等しいファイル名はファイルの作成日の順序で書き込みます。
すべての入力の並べ替えが終わるまで、このプロセスを繰り返します。
.NET Framework での正規化形式のサポートの詳細については、NormalizationForm 列挙体の説明を参照してください。 文字列の正規化の詳細については、Normalize メソッドのトピックを参照してください。
正規化、文字の分解、および等値の詳細については、Unicode ホーム ページにある「Unicode Standard Annex #15」の「Unicode Normalization Forms」を参照してください。