Ответ 1
Модуль unicodedata
предлагает функцию .normalize()
, которую вы хотите нормализовать в форме NFC:
>>> unicodedata.normalize('NFC', u'\u0061\u0301')
u'\xe1'
>>> unicodedata.normalize('NFD', u'\u00e1')
u'a\u0301'
NFC или "Normal Form Composed" возвращает сгенерированные символы, NFD, "Normal Form Decomposed" дает вам разложенные комбинированные символы.
Дополнительные формы NFKC и NFKD относятся к кодовым точкам совместимости; например U + 2160 (ROMAN NUMERAL ONE) на самом деле то же самое, что и U + 0049 (LATIN CAPITAL LETTER I), но присутствует в стандарте Unicode, чтобы оставаться совместимым с кодировками, которые обрабатывают их отдельно. Использование формы NFKC или NFKD в дополнение к составлению или разложению символов также заменит все символы совместимости на их каноническую форму:
>>> unicodedata.normalize('NFC', u'\u2167') # roman numeral VIII
u'\u2167'
>>> unicodedata.normalize('NFKC', u'\u2167') # roman numeral VIII
u'VIII'
Обратите внимание, что нет никакой гарантии, что составленные и разложенные формы являются коммуникативными; нормализация комбинированного символа в форме NFC, то преобразование результата обратно в форму NFD не всегда приводит к одной и той же последовательности символов. Стандарт Unicode содержит список исключений; символы в этом списке могут быть скомбинированы, но не разложимы обратно в их комбинированную форму по разным причинам. Также см. Документацию в таблице исключения композиций.