2013-05-09 10 views
35

Czy w Pythonie istnieje standardowa metoda normalizowania łańcucha znaków Unicode, aby zawierał on tylko najprostsze jednostki Unicode, które można wykorzystać do ich reprezentacji?Normalizowanie Unicode

Mam na myśli coś, co tłumaczy sekwencję taką jak ['LATIN SMALL LETTER A', 'COMBINING ACUTE ACCENT'] na ['LATIN SMALL LETTER A WITH ACUTE']?

zobaczyć, gdzie jest problem:

>>> import unicodedata 
>>> char = "á" 
>>> len(char) 
1 
>>> [ unicodedata.name(c) for c in char ] 
['LATIN SMALL LETTER A WITH ACUTE'] 

Ale teraz:

>>> char = "á" 
>>> len(char) 
2 
>>> [ unicodedata.name(c) for c in char ] 
['LATIN SMALL LETTER A', 'COMBINING ACUTE ACCENT'] 

Mógłbym, oczywiście, iteracyjne nad wszystkie znaki i zrobić ręcznie zamienniki itp, ale to nie jest sprawna i jestem prawie pewna, że ​​przegapiłabym połowę specjalnych przypadków i popełniłbym błędy.

Odpowiedz

60

Moduł unicodedata oferuje .normalize() function, chcesz znormalizować do formularza NFC:

>>> unicodedata.normalize('NFC', u'\u0061\u0301') 
u'\xe1' 
>>> unicodedata.normalize('NFD', u'\u00e1') 
u'a\u0301' 

NFC lub 'Normal Form Złożony' powraca złożone postacie, NFD, 'Normal Form rozkładowi' daje rozkładowi, połączone znaki.

Dodatkowe formularze NFKC i NFKD dotyczą kodepopów zgodności; na przykład U + 2160 (ROMAN NUMERAL ONE) to tak naprawdę to samo co U + 0049 (LATIN CAPITAL LETTER I), ale obecny w standardzie Unicode, aby zachować kompatybilność z kodowaniem, które traktuje je osobno. Przy użyciu NFKC lub NFKD formę, oprócz komponowania lub rozkładających znaków, będzie również zastąpić wszystkie znaki „Zgodność” z ich postaci kanonicznej:

>>> unicodedata.normalize('NFC', u'\u2167') # roman numeral VIII 
u'\u2167' 
>>> unicodedata.normalize('NFKC', u'\u2167') # roman numeral VIII 
u'VIII' 

pamiętać, że nie ma gwarancji, że w składzie i rozkładane formy są komunikatywne; normalizowanie postaci łączonej do postaci NFC, a następnie przekształcenie wyniku z powrotem w formularz NFD nie zawsze skutkuje tą samą sekwencją znaków. Standard Unicode maintains a list of exceptions; Znaki na tej liście można składać, ale nie mogą się rozkładać z powrotem do ich połączonej postaci, z różnych powodów. Zobacz także dokumentację na stronie Composition Exclusion Table.

+0

Wśród tych form, NFC jest najbliżej spełnienia wymogu "obejmuje tylko najprostsze jednostki unicode, które mogą być używane do reprezentowania go" interpretowane jest jako odnosząca się do najmniejszej liczby punktów kodu Unicode. Jednak NFC wpływa również na inne rzeczy, np. zastępowanie znaków ich odpowiednikami kanonicznymi. Aby wykonać * tylko * część minimalizacji, obawiam się, że musiałbyś ją zaprogramować samodzielnie. –