Это в основном теоретический вопрос, который мне очень любопытен. (Я не пытаюсь сделать это, кодируя это сам или что-то в этом роде, я не изобретаю колеса.)
Мой вопрос в том, как таблица эквивалентности прописных и строчных букв работает для Unicode.
Например, если бы мне пришлось сделать это в ASCII, я бы взял символ, и если бы он попал в диапазон [a-z], я бы суммировал разницу между A и a.
Если он не попадает в этот диапазон, у меня была бы небольшая таблица эквивалентности для 10 или около того символов с диакритическими знаками плюс ñ. (Или я мог бы просто иметь полный массив эквивалентности с 256 записями, большинство из которых были бы такими же, как входные)
Однако я предполагаю, что есть лучший способ указать эквиваленты в Unicode, учитывая, что есть сотни тысяч символов и что теоретически можно добавить новый язык или набор символов (и я ожидаю, что вы когда это произойдет, не потребуется исправлять окна).
Есть ли в Windows огромная жестко закодированная таблица эквивалентности для каждого символа? Или как это реализовано?
Связанный с этим вопрос заключается в том, как SQL Server реализует запросы на основе Unicode, нечувствительные к акценту и регистру. Есть ли у него внутренняя таблица, в которой говорится, что все é ë è E É È и Ë эквивалентны "e"?
Когда дело доходит до сравнения струн, это звучит не очень быстро.
Как быстро получить доступ к индексам? Он уже индексирует значения, преобразованные в их «базовые» символы, соответствующие параметрам сортировки этого поля?
Кто-нибудь знает внутренности этих вещей?
Спасибо!
«небольшая таблица эквивалентности для 10 или около того знаков с ударением плюс -» - вы должны понимать, что «маленький» означает примерно в 100 раз больше, чем вы думали.
Я не совсем уверен, что понимаю, почему все варианты на e, которые я не могу легко набрать на клавиатуре, все равны "e". Я могу понять это с точки зрения базы данных (для поиска, игнорирующего специальные акценты), но с точки зрения языка это все разные символы ...
почему вы всегда говорите о "окнах ...", когда ваш вопрос теоретический? Если вам нужен хороший алгоритм, не запускайте его где-нибудь в какой-либо ОС, а ищите библиотеку Unicode или просто алгоритм. извините, но этот вопрос звучит как "я знаю, что окна делают что-то, поэтому они должны это делать" ...





Существует файл сопоставления, который содержит все сопоставления случаев, которые имеют соотношение сопоставления 1: 1. Обычно операционные системы / фреймворки / библиотеки поддерживают определенную версию Unicode, и поскольку этот файл сопоставлений случаев является версионным, вы получите сопоставления для той версии Unicode, которая поддерживается вашей конкретной ОС / фреймворком / библиотекой / всем, что случилось.
Для получения дополнительной информации о сопоставлении регистра Unicode см .: http://www.unicode.org/faq/casemap_charprop.html
В большинстве систем письма нет отдельных прописных и строчных букв. Согласно Википедии, исключения включают «римский, греческий, кириллический и армянский алфавиты».
Так что не так уж много писем, о которых стоит беспокоиться. Эта страница показывает, что большие диапазоны символов следуют простой схеме добавления 1 к символу верхнего регистра, чтобы получить эквивалент в нижнем регистре (хотя, конечно, есть некоторые исключения).
Я собираюсь обратиться к части этого вопроса, касающейся MS SQL Server, но «правильный» ответ на самом деле зависит от поддерживаемого языка (языков) и приложения.
Когда вы создаете таблицу в SQL Server, каждое текстовое поле имеет неявно или явно заданное сопоставление. Это влияет как на порядок сортировки, так и на поведение сравнения. По умолчанию для большинства языковых стандартов английского языка (США) используется Latin1_General_CI_AS или Latin 1, без учета регистра, с учетом диакритических знаков. Это означает, например, что a = A, но a! = Ä и a! = Ä. Вы также можете использовать нечувствительность к акценту (Latin1_General_CI_AI), которая рассматривает все диакритические вариации буквы «A» как равные.
Некоторые языковые стандарты поддерживают другие категории сравнения; например, во французском языке слова, содержащие диакритические знаки, упорядочиваются несколько иначе, чем в немецком. Турецкий считает, что i без точки и i с точками семантически различаются, поэтому I и i не совпадают даже с нечувствительными к регистру сравнениями, если вы используете турецкую сортировку без учета регистра и с учетом акцента.
Вы можете изменить параметры сортировки для каждой базы данных, для каждой таблицы, для каждого поля и, за определенную плату, даже для каждого запроса. Насколько я понимаю, индексы нормализуются в соответствии с указанным порядком сопоставления, что означает, что в основном индекс сохраняет сглаженную версию исходной строки. Например, при сопоставлении без учета регистра яблоко и яблоко хранятся как яблоко. Перед поиском запросы выравниваются с использованием той же сортировки.
В японском языке существует еще одна категория нормализации, где символы полной и половинной ширины, такие как ア = ア, а в некоторых случаях два символа половинной ширины сглаживаются до одного семантически эквивалентного символа (バ = バ). Наконец, для некоторых языков есть еще один восковой шар с составными символами, где отдельные диакритические символы могут быть составлены с другими символами (например, умляут в ä - это один символ, составленный с простой формой a). В этой категории есть вариации на вьетнамском, тайском и некоторых других языках. Если есть каноническая форма, нормализация Unicode позволяет рассматривать составные и разложенные формы как эквивалентные. Нормализация Unicode обычно применяется до проведения каких-либо сравнений.
Подводя итог, для сравнения без учета регистра вы делаете то же самое, что и при сравнении строк диапазона ASCII: выравнивайте левую и правую стороны сравнения «в нижний регистр» (например), затем сравнивайте массив как двоичный множество. Разница в том, что вам нужно 1) нормализовать строки к той же форме Unicode (kC или kD) 2) нормализовать строки к одному и тому же регистру в соответствии с правилами этой локали 3) нормализуйте акценты в соответствии с правилами чувствительности к акцентам 4) сравнить по бинарному сравнению 4) если применимо, например, в случае сортировки, сравните с использованием дополнительных вторичных и тернарных правил сортировки, которые включают в себя вещи, аналогичные вещам вроде «Mc» сортирует перед «M» в некоторых языках.
И да, Windows хранит таблицы для всех этих правил. Вы не получаете их все по умолчанию при каждой установке, если только вы не добавите их поддержку с помощью поддержки восточноазиатских языков и поддержки сложных сценариев с панели управления.
Правильный ответ немного сложнее, в зависимости от того, что вы пытаетесь сделать.
При сравнении символьных строк для приложений сортировки или поиска правильный алгоритм для использования указывается в UTS № 10: «Алгоритм сортировки Unicode».. Нечувствительность к регистру является частью смеси, но существуют разные способы представления множества символов, и приложениям часто приходится рассматривать различные представления как эквивалент.
Правила сортировки зависят от региона. В основном это проблема, когда вы сортируете результаты для отображения пользователю. Игнорирование правил может расстроить пользователей и даже привести к уязвимости системы безопасности.
Если вы просто пытаетесь использовать слова с большой буквы для отображения, правила там тоже могут быть хитрыми; есть преобразования "один ко многим" и другие проблемы. В зависимости от языкового стандарта одна и та же буква может использоваться по-разному. Положение буквы в слове может иметь значение. Также существует четкое понятие «заглавный регистр», когда вы просто хотите использовать первую букву каждого слова с заглавной буквы. Иногда регистр заголовка символа не совпадает с его верхним регистром.
Я ожидаю, что вам нужно будет патчить окна, если они добавят новый набор символов в unicode, но это будет патч с очень низким приоритетом, поскольку изначально никто не будет использовать эти символы.