Есть ли способ сравнить арабские символы без учета их начальной / средней / конечной формы?
В латинском алфавите буквы имеют прописные и строчные буквы. В Python, если вы хотите сравнить две строки без учета их регистра, вы можете преобразовать их в один и тот же регистр, используя 'string'.upper()
или же 'string'.lower()
В арабском письме буквы могут иметь начальную, среднюю или окончательную форму. Есть ли аналогичный способ сравнения строк арабских символов без заботы о том, в какой форме находятся буквы?
1 ответ
Здесь есть две части, которые должны работать для всех языков: *
- Ваши строки должны быть в нормализации NFKD, чтобы гарантировать, что две одинаковые строки имеют одинаковые кодовые единицы.
- Чтобы игнорировать регистр при сравнении двух строк NFKD, используйте алгоритм сворачивания регистра Unicode.
Между ними, это обрабатывает английский верхний и нижний регистр, арабский начальный / средний / окончательный (плюс изолированные), немецкий ß
против ss
, é
как единая кодовая точка против e\N{COMBINING ACUTE ACCENT}
Китайские повернутые иероглифы, японская кана полуширины и, возможно, множество других вещей, о которых вы даже не думали.
В Python это выглядит так:
>>> s1 = 'ﻧ'
>>> s2 = 'ﻨ'
>>> unicodedata.normalize('NFKD', s1).casefold() == unicodedata.normalize('NFKD', s2)
True
Обратите внимание, что casefold
не был добавлен до Python 3.3. Если вы используете более раннюю версию Python, в PyPI есть реализации; их использование должно быть похоже на использование встроенной версии 3.3+.
Если вас интересует, как именно это работает для арабского языка, а не просто тот факт, что он работает для арабского языка наряду с любым другим языком, вы прочитали алгоритмы и таблицы на unicode.org. IIRC, документ W3C, который рекомендует делать это, объясняет, почему он работает, используя арабский язык в качестве примера. Я полагаю, что это потому, что Unicode рассматривает начальную, медиальную, конечную и изолированную как эквивалентные формам представления совместимости одного и того же символа, поэтому нормализация до декомпозиции дает вам эффективную изолированную форму плюс модификатор, который может пропускать или преобразовывать регистр, даже если он происходит непосредственно комбинированный символ просто возвращает сам символ.
* Есть несколько случаев, когда два разных языка или культуры используют один и тот же сценарий, но имеют разные правила сворачивания регистра; в этом случае вам нужно привязать регистр к конкретному языку, который Python не включает. Но это не должно быть актуально здесь.