Как вы устанавливаете строки в верхнем или нижнем регистре в Юникоде?
Это в основном теоретический вопрос, о котором мне очень любопытно. (Я не пытаюсь это сделать, кодируя его сам или что-то еще, я не изобретаю колеса).
Мой вопрос в том, как верхняя/нижняя регистр эквивалентности работает для 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" . Нечувствительность к регистру является частью микса, но существуют разные способы представления множества символов, и приложениям часто приходится рассматривать различные представления как эквивалентные.
Правила сортировки зависят от языка. Это в основном проблема, когда вы сортируете результаты для отображения пользователю. Игнорирование правил может помешать пользователям и даже привести к уязвимостям безопасности.
Если вы просто пытаетесь использовать слова для показа для показа, правила там тоже могут быть сложными; есть конверсии "один ко многим" и другие проблемы. В зависимости от локали одна и та же буква может капитализироваться по-разному. Позиция букв в слове может иметь значение. Также существует четкое понятие "титульный регистр", в котором вы просто хотите загладить первую букву каждого слова. Иногда заголовок символа не совпадает с его верхним регистром.