나는 내가 작성한 Java 프로그램에서 정렬을 위해 unix sort 명령을 사용합니다. 그러나 Java 문자열 비교가 정렬 비교와 다르게 동작한다는 사실로 인해 문제가 발생했습니다.
[Java 문서][1]에서:
두 문자열을 사전순으로 비교합니다. 비교는 문자열에 있는 각 문자의 유니코드 값을 기반으로 합니다.
정렬 매뉴얼 페이지에서:
* 경고하다 * 환경에 의해 지정된 로캘은 정렬 순서에 영향을 미칩니다. 기본 바이트 값을 사용하여 기존 정렬 순서를 얻으려면 LC_ALL=C를 설정합니다.
그래서 내 생각엔 정렬에 LC_ALL=C 를 사용해야 할 것 같습니다. 그러나 나는 항상 이것이 ASCII 값을 기준으로 정렬하는 것을 의미한다고 생각했습니다. 이는 유니코드에서 어떤 일이 일어날지 누가 알 수 있는지 의미합니다.
답변1
이것LC_COLLATE
로케일카테고리는 정렬 순서를 제어합니다. LC_ALL
모든 카테고리를 설정합니다.
를 사용하면 LC_COLLATE=C
문자열이 바이트별로 정렬됩니다. 바이트는 필요하지 않습니다ASCII 코드문자(0에서 127 사이의 바이트 값만 ASCII입니다). Unix 시스템에서 유니코드는 거의 항상 다음과 같이 인코딩됩니다.UTF-8. UTF-8에는 문자를 바이트 시퀀스로 인코딩할 때 문자 순서를 유지하는 속성이 있으므로 UTF-8 문자열을 바이트 사전 순서로 정렬하는 것은 문자 사전 순서로 정렬하는 것과 같습니다. 따라서 LC_COLLATE=C
UTF-8로 인코딩된 유니코드를 문자 값을 기준으로 사전순으로 정렬하는 것이 적합합니다.
Java는 실제로 유니코드 문자 값을 기준으로 정렬하지 않고 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
첫 번째 패스에서는 두 번째 패스에서는 코드 포인트별로 정렬됩니다.