Как вы устанавливаете строки в верхнем или нижнем регистре в Юникоде?

Это в основном теоретический вопрос, о котором мне очень любопытно. (Я не пытаюсь это сделать, кодируя его сам или что-то еще, я не изобретаю колеса).

Мой вопрос в том, как верхняя/нижняя регистр эквивалентности работает для Unicode.

Например, если бы мне пришлось сделать это в ASCII, я бы взял символ, и если он упадет с диапазоном [a-z], я бы суммировал разницу между A и a.

Если он не попадает в этот диапазон, у меня будет небольшая таблица эквивалентности для 10 или более акцентированных символов плюс. (Или я мог бы просто иметь полный массив эквивалентности с 256 элементами, большинство из которых было бы таким же, как и вход)

Однако я предполагаю, что есть лучший способ указать эквиваленты в Unicode, учитывая, что есть сотни тысяч символов, и что теоретически можно добавить новый язык или набор символов (и я ожидая, что вам не понадобится патч окна, когда это произойдет).

Есть ли у Windows огромная жестко закодированная таблица эквивалентности для каждого символа? Или как это реализовано?

Связанный вопрос заключается в том, как SQL Server реализует Unicode-основанные на акцентах и ​​без учета регистра запросы. У него есть внутренняя таблица, в которой говорится, что é è è E É È и Ë эквивалентны "e"?

Это не звучит очень быстро, когда дело доходит до сравнения строк.

Как он быстро обращается к индексам? Он уже индексирует значения, преобразованные в их "базовые" символы, соответствующие этой сортировке полей?

Кто-нибудь знает внутренности для этих вещей?

Спасибо!

Ответы

Ответ 1

Существует файл сопоставления, который содержит все сопоставления случаев, которые имеют коэффициент отображения 1:1. Обычно операционные системы/фреймворки/библиотеки поддерживают определенную версию Unicode, и поскольку файл сопоставлений этого случая версируется, вы получите сопоставления для любой версии Unicode вашей конкретной ОС/framework/library/независимо от того, что случилось с ней.

Для получения дополнительной информации о сопоставлениях кодов Unicode см.: http://www.unicode.org/faq/casemap_charprop.html

Ответ 2

Я собираюсь обратиться к части MS SQL Server этого вопроса, но "правильный" ответ на самом деле зависит от поддерживаемых языков и приложений.

Когда вы создаете таблицу в SQL Server, каждое текстовое поле имеет либо неявное, либо явно заданное сопоставление. Это влияет как на порядок сортировки, так и на поведение сравнения. По умолчанию для большинства английских (US) локалей является Latin1_General_CI_AS или Latin 1, нечувствительный к регистру, Accent-Sensitive. Это означает, что, например, a = A, но a!= Ä и a!= Ä. Вы также можете использовать без акцента (Latin1_General_CI_AI), который рассматривает все диакритические вариации "A" как равные.

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

Вы можете изменить сортировку для каждой базы данных, таблицы, поля и, с некоторой стоимостью, даже для каждого запроса. Я понимаю, что индексы нормализуются в соответствии с указанным порядком сортировки, что означает, что в основном индекс сохраняет сглаженную версию исходной строки. Например, при нечувствительных к регистру коллаборациях Apple и яблоко хранятся в виде яблока. Запросы выравниваются с той же сортировкой перед поиском.

На японском языке существует еще одна категория нормализации, где символы полной ширины и полуширины, такие как ア = ア, а в некоторых случаях два символа полуширины сплющены до одного семантически эквивалентного символа (バ = バ). Наконец, для некоторых языков есть еще один шар воска с составными символами, где изолированные диакритические символы могут быть скомбинированы с другими символами (например, умлаут в ä - один символ, составленный с простой формой a). Вьетнамский, тайский и несколько других языков имеют вариации этой категории. Если существует каноническая форма, нормализация Юникода позволяет рассматривать составные и разложенные формы как эквивалентные. Нормализация Юникода обычно применяется до того, как будут сделаны какие-либо сравнения.

Подводя итог, для нечувствительного к регистру сравнения вы делаете что-то похожее на то, что вы хотели бы при сравнении строк ASCII-диапазона: сгладить левую и правую стороны сравнения "в нижнем регистре" (например), а затем сравнить массив как двоичный массив. Разница в том, что вам нужно 1) нормализовать строки в одну и ту же форму юникода (kC или kD) 2) нормализовать строки в одном и том же случае в соответствии с правилами этого языка 3) нормализовать акценты в соответствии с правилами чувствительности к акценту 4) сравнить в соответствии с двоичным сравнением 4) если применимо, например, в случае сортировки, сравните с помощью дополнительных правил вторичной и тройной сортировки, которые включают в себя такие вещи, как "Mc", до "M" на некоторых языках.

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

Ответ 3

Большинство письменных систем не имеют отдельных прописных и строчных букв. Согласно Википедии, исключения включают "римский, греческий, кириллический и армянский алфавиты".

Итак, не так много писем, о которых нужно беспокоиться. Эта страница показывает, что большие диапазоны символов следуют простой схеме добавления 1 к символу верхнего регистра, чтобы получить нижний регистр (хотя, конечно, есть некоторые исключения).

Ответ 4

Правильный ответ немного сложнее, в зависимости от того, что вы пытаетесь сделать.

При сравнении строк символов, для сортировки или поиска приложений, правильный алгоритм для использования указан в UTS # 10: "Алгоритм сортировки Unicode" . Нечувствительность к регистру является частью микса, но существуют разные способы представления множества символов, и приложениям часто приходится рассматривать различные представления как эквивалентные.

Правила сортировки зависят от языка. Это в основном проблема, когда вы сортируете результаты для отображения пользователю. Игнорирование правил может помешать пользователям и даже привести к уязвимостям безопасности.

Если вы просто пытаетесь использовать слова для показа для показа, правила там тоже могут быть сложными; есть конверсии "один ко многим" и другие проблемы. В зависимости от локали одна и та же буква может капитализироваться по-разному. Позиция букв в слове может иметь значение. Также существует четкое понятие "титульный регистр", в котором вы просто хотите загладить первую букву каждого слова. Иногда заголовок символа не совпадает с его верхним регистром.