2013-05-29 3 views
1

Не знаю, на каком сайте этот вопрос точно соответствует, поэтому разместите его здесь.Таблица символов сортировки символов Unicode по умолчанию

Я использую Postgresql 9.2 на RHEL 6.4 и соблюдать следующие правила:

select foo 
from unnest('{а,ә,б,в,г,д,е,ж}'::text[]) as foo 
order by foo collate "kk_KZ.utf8" 

дает

а 
ә 
б 
в 
г 
д 
е 
ж 

НО

select foo 
from unnest('{а,ә,б,в,г,д,е,ж}'::text[]) as foo 
order by foo collate "en_US.utf8" 

дает

а 
б 
в 
г 
д 
е 
ә -- misplaced 
ж 

Кроме того, я обнаружил, что имеется таблица элементов сортировки Unicode по умолчанию [1], в которой указан соответствующий символ (04D9; [.199D.0020.0002.04D9] # CYRILLIC SMALL LETTER SCHWA) в правильном порядке.

Я понимаю, что глупо ожидать, что кириллические символы будут обрабатываться должным образом с помощью локали «en_US.utf8», но что такое правильное поведение Unicode или любых других соответствующих стандартов в случаях, когда символ обычно не принадлежит язык/язык, используемый для сортировки?

[1] http://www.unicode.org/Public/UCA/latest/allkeys.txt

+0

FYI: glibc 2.28, который будет выпущен 2018-08-01, был синхронизирован с ISO-14651: 2016 (сам синхронизирован с Unicode 9) и будет использовать ожидаемый заказ для en_US. – ninjalj

ответ

2

Это не неуместны. Это может быть для вас, но это не для меня. :-) По всей серьезности, нет никакого правильного поведения Unicode; просто не может быть. Набор символов - это отображение; сопоставление - это набор правил, специфичных для локали, для сортировки символов в этом наборе - и даже в пределах одного языка может быть несколько сопоставлений.

В документах ICU есть яркие примеры того, насколько тернист этот материал приобретает, на случай, если вам интересно. Цитирование обширно:

http://userguide.icu-project.org/collation

[H] прежде чем некоторые из способов языков различаются по заказывающим строкам:

Буквы A-Z может быть отсортирован в другом порядке, чем на английском языке. Например, на литовском языке «y» сортируется между «i» и «k».

Сочетания букв можно трактовать так, как если бы они были одной буквой. Например, в традиционном испанском языке «ch» рассматривается как одна буква и сортируется между «c» и «d».

Акцентированные буквы можно трактовать как второстепенные варианты безударной буквы. Например, «é» можно рассматривать эквивалентно «e».

Акцентированные буквы можно рассматривать как разные буквы. Например, «Å» на датском языке рассматривается как отдельное письмо, которое сортируется сразу после «Z».

Несоответствующие буквы, которые считаются отличными на одном языке, могут быть нечеткими в другом. Например, буквы «v» и «w» являются двумя разными буквами в соответствии с английским. Однако «v» и «w» считаются вариантами одного и того же письма на шведском языке.

Письмо можно трактовать так, как если бы это были две буквы. Например, в традиционном немецком «ä» сравнивается, как будто это «ae».

Тайский требует, чтобы порядок определенных букв был отменен.

Французский требует, чтобы буквы, отсортированные с акцентами в конце строки, сортировались впереди акцентов в начале строки. Например, слово «côte» сортируется до «coté», потому что острый акцент на последнем «e» более значителен, чем огибающий на «o».

Иногда буквы нижнего регистра сортируются до прописных букв. Реверс требуется в других ситуациях. Например, строчные буквы обычно сортируются до заглавных букв на английском языке. Письма в латышском письме - полная противоположность.

Даже на том же языке различным приложениям могут потребоваться разные заказы сортировки. Например, в немецких словарях «öf» будет предшествовать «из». В телефонных книгах ситуация противоположная.

Порядок сортировки может меняться со временем из-за правительственных постановлений или новых символов/сценариев в Юникоде.

+0

Нет ли какой-либо «резервной копии по умолчанию», когда символ не имеет значения в определенной локали? – Tair

2

Unicode Collation Algorithm позволяет производить любые заказы в DUCET.

Не существует «правильного» поведения. Есть различные способы поведения, которые можно было бы ожидать, и наиболее подходящее зависит от контекста, аудитории. Иногда любое поведение может быть правильным, так как на самом деле нет причины принуждать любой порядок кириллических алгоритмов в американском английском сопоставлении.

Common Locale Data Repository обеспечивает привязки к языку для DUCET. CLDR использует LDML (язык разметки локальных данных), чтобы указать настройки, а синтаксис - Unicode Technical Specification #35, part 5.

В последней версии данных, предоставленных CLDR для en_US, нет настроек: используется modified version of the DUCET (как указано в UTS № 35 в разделе «Корневая сортировка»). Он перечисляет кириллицу schwa после кириллицы A, т. Е. Порядка, который вы ожидали.

Существует также данные для локали en_US_POSIX, и это включает некоторые изменения, но ничто не изменяет ничего, что не в ASCII.

Похоже, что локальная система en_US, установленная в вашей системе, использует пошив, который помещает schwa рядом с E, вероятно, из-за их аналогичной формы. Можно утверждать, что это вызовет меньше удивления для американской английской аудитории, чем сортировка schwa после A: спросите людей, что это такое, и посмотрите, сколько всего скажет вам, что это «перевернутый E». Это неправильно или неправильно, но если вы спросите меня, это кажется более подходящим, чем сопоставление, найденное в CLDR.

+0

У вас есть ссылки, в которых говорится, что «любое поведение может быть правильным»? Спасибо! – Tair

+0

Нет. Я основываю это утверждение на том, что на английском языке нет правил сортировки кириллических букв (должно быть очевидно, почему) и того факта, что некоторые аудитории ожидают одного порядка, а некоторые другие ожидают другого. –

1

Postgresql использует локали, предоставляемые операционной системой. В вашей настройке локали предоставляются glibc. Glibc использует сильно модифицированную версию «древней» версии ISO 14651 (см. glibc Bug 14095 - Review/update collation data from Unicode/ISO 14651 для получения информации о текущих проблемах при попытке обновить данные локали glibc).

Начиная с версии glibc 2.28, выпущенной 2018-08-01, glibc будет использовать данные из ISO 14651: 2016 (который синхронизирован с Unicode 9) и даст порядок, ожидаемый OP для en_US.

ISO 14651 является Метод сравнения строк символов и описание общего шаблона настраиваемого упорядочения и он похож на UCA, с некоторыми отличиями. CTT (Общий шаблон таблицы) является эквивалентом ISO14651 DUCET, и они выровнены.

В первый раз CYRILLIC SMALL LETTER SCHWA появился в таблице сопоставлений в glibc, был для az_AZ locale (азербайджанский), где он был заказан после CYRILLIC SMALL LETTER IE. Это соответствует:

commit fcababc4e18fee81940dab20f7c40b1e1fb67209 
Author: Ulrich Drepper <[email protected]> 
Date: Fri Aug 3 08:42:28 2001 +0000 

    Update. 

    2001-08-03 Ulrich Drepper <[email protected]> 

     * locale/iso-639.def: Add Tigrinya. 

Оттуда, что упорядочение в конце концов переехал в файл iso14651_t1 как на Bug 672 - Include iso14651_t1 in collation rules, которая была попыткой упростить данные Glibc локалей. Это соответствует:

commit 5d2489928c0040d2a71dd0e63c801f2cf98e7efc 
Author: Ulrich Drepper <[email protected]> 
Date: Sun Feb 18 04:34:28 2007 +0000 

    [BZ #672] 

    2005-01-16 Denis Barbier <[email protected]> 
     [BZ #672] 
     * locales/ca_ES: Replace current collation rules by including 
     iso14651_t1 and adding extra rules if needed. There should be 
     no noticeable changes in sorted text. only ligatures and 
     ignoreable characters have modified weights. 
     * locales/da_DK: Likewise. 
     * locales/en_CA: Likewise. 
     * locales/es_US: Likewise. 
     * locales/fi_FI: Likewise. 
     * locales/nb_NO: Likewise. 

     [BZ #672] 
     * locales/iso14651_t1: Simplified. Extended. 

Большинство районов в начале GLibC от iso14651_t1, и адаптировать его, что это то, что вы видите с en_US.

В то время как glibc основывается на стандартном заказе на азербайджанском языке, DUCET вместо этого основывает его на заказе для казахского и татарского, откуда и происходит разница.

Смежные вопросы