
私は私が書いたJavaプログラムでソートするためにunix sortコマンドを使います。しかし、Java文字列比較がソート比較とは異なる動作をするという事実が原因で問題が発生しました。
[Javaドキュメント][1]から:
2つの文字列をアルファベット順に比較します。比較は、文字列内の各文字のUnicode値に基づいています。
ソートマニュアルページから:
*警告する* 環境で指定されたロケールはソート順に影響します。デフォルトのバイト値を使用して既存のソート順序を取得するには、LC_ALL = Cを設定します。
だから私の考えでは、ソートにLC_ALL = Cを使用する必要があるようです。しかし、私はいつもこれがASCII値に基づいてソートすることを意味すると思いました。これは、Unicodeで何が起こるのか、誰が知っているのかを意味します。
答え1
これLC_COLLATE
ロケールカテゴリはソート順を制御します。LC_ALL
すべてのカテゴリを設定します。
を使用すると、LC_COLLATE=C
文字列はバイト単位でソートされます。バイトは必要ありませんASCIIコード文字(0から127までのバイト値のみがASCIIです)。 Unixシステムでは、Unicodeはほぼ常に次のようにエンコードされます。UTF-8。 UTF-8には、文字をバイトシーケンスにエンコードするときに文字順序を保持する属性があるため、UTF-8文字列をバイト辞書順序で並べ替えることは、文字辞書順序で並べ替えるのと同じです。したがって、LC_COLLATE=C
UTF-8でエンコードされたUnicodeを文字値に基づいてアルファベット順にソートすることが適切です。
Javaは実際にUnicode文字値に基づいてソートするのではなく、UTF-16エンコーディングに基づいてソートします。これは以下に関連しています。エージェントペアつまり、コードポイントが65535より高い場合です。
UTF-8バイト表現のソート、Javaソート、およびsort
GNU / LinuxのUTF-8ロケールユーティリティは許可されていません。文字の組み合わせたとえば、á
(U+0061 LATIN SMALL LETTER A の後の U+0301 COMBINING ACUTE ACCENT) は (U+00E1 LATIN SMALL LETTER A WITH ACUTE) とは異なるように整列されます (UTF-8 ロケールでは両方とも同じでá
終わります) 。a
最初のパスでは、2番目のパスではコードポイントでソートされます。