Почему ICU4J не соответствует порядку сортировки UTF-8?

Мне трудно понять порядок сортировки Unicode.

Когда я запускаю Collator.getInstance(Locale.ENGLISH).compare("_", "#") под ICU4J 55.1, я получаю возвращаемое значение -1, указывающее, что _ предшествует #.

Однако, глядя на http://www.utf8-chartable.de/unicode-utf8-table.pl?utf8=dec Я вижу, что # (U+0023) предшествует _ (U+005F). Почему ICU4J возвращает значение -1?


person Gili    schedule 21.09.2015    source источник
comment
Порядок отдельных символов основан на таблице сопоставления, которая имеет мало отношения к номерам кодов. Для начала см. unicode.org/reports/tr10/.   -  person Mark Ransom    schedule 22.09.2015
comment
@MarkRansom Где можно найти таблицу сопоставления для американского английского? Спецификация юникода очень тяжелая, и я не смог найти ссылку на нее.   -  person Gili    schedule 22.09.2015
comment
Если вы перейдете по первой ссылке на этой странице, она приведет к allkeys.txt, что дает порядок сортировки по умолчанию. _ это 005F ; [*020B.0020.0002] # LOW LINE, а # это 0023 ; [*0391.0020.0002] # NUMBER SIGN. Обратите внимание, что числа для _ меньше, чем числа для #.   -  person Mark Ransom    schedule 22.09.2015
comment
@MarkRansom Я считаю, что это отвечает на мой вопрос. Пожалуйста, опубликуйте официальный ответ, и я отмечу его как принятый   -  person Gili    schedule 22.09.2015


Ответы (2)


Во-первых, UTF-8 — это просто кодировка. Он указывает, как физически хранить кодовые точки Unicode, но не обрабатывает сортировку, сравнения и т. д.

Теперь страница, на которую вы ссылаетесь, показывает все в числовом порядке кодовых точек. Это порядок сортировки при использовании двоичной сортировки (в SQL Server это будут сортировки с именами, оканчивающимися на _BIN и _BIN2). Но небинарное упорядочение гораздо сложнее. Правила описаны здесь: Алгоритм сопоставления Unicode (UCA).

Основные правила находятся здесь: http://www.unicode.org/repos/cldr/tags/release-28/common/uca/allkeys_CLDR.txt

Это показывает:

005F  ; [*010A.0020.0002] # LOW LINE
...
0023  ; [*0290.0020.0002] # NUMBER SIGN

Очень важно помнить, что любая локаль/культура может переопределить эти базовые правила. Следовательно, хотя несколько строк, отмеченных выше, объясняют это конкретное обстоятельство, другие обстоятельства должны быть проверены http://www.unicode.org/repos/cldr/tags/release-28/common/collation/, чтобы узнать, есть ли какие-либо переопределения, зависящие от локали.

person Solomon Rutzky    schedule 22.09.2015

Преобразование комментариев Марка Рэнсома в ответ:

  • Порядок отдельных символов основан на таблице сопоставления, которая имеет мало отношения к номерам кодов. См.: http://www.unicode.org/reports/tr10/#Default_Unicode_Collation_Element_Table
  • Если вы перейдете по первой ссылке на этой странице, она приведет к allkeys.txt который дает порядок сортировки по умолчанию.
  • В частности, _ — это 005F ; [*020B.0020.0002] # LOW LINE, а # — это 0023 ; [*0391.0020.0002] # NUMBER SIGN. Обратите внимание, что номера сортировки для _ меньше, чем номера для #.
person Gili    schedule 21.09.2015
comment
Марк Рэнсом близок, но не на 100%. Я опубликую ответ через 30-45 минут... - person Solomon Rutzky; 22.09.2015