2013-05-09 129 views
35

在Python中是否有一種標準化方式來標準化unicode字符串,以便它只理解可用於表示它的最簡單的unicode實體?正常化Unicode

我的意思是,這樣會將一個序列像['LATIN SMALL LETTER A', 'COMBINING ACUTE ACCENT']翻譯爲['LATIN SMALL LETTER A WITH ACUTE']

看到的問題是:

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

但現在:

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

我當然可以,遍歷所有的字符和做手工更換等,但它不是高效率,我敢肯定我會錯過一半的特殊情況,並犯錯誤。

回答

60

unicodedata模塊提供了.normalize() function,要歸到NFC形式:

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

NFC,或由字符回報,NFD,「範式風化」爲您提供了分解「組成範式」,組合字符。

額外的NFKC和NFKD形式處理兼容性代碼點;例如U + 2160(ROMAN NUMERAL ONE)實際上與U + 0049(拉丁大寫字母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標準maintains a list of exceptions;出於各種原因,此列表中的字符是可組合的,但不能分解回其組合形式。另請參閱Composition Exclusion Table上的文檔。

+0

在這些形式中,NFC最接近符合要求「它只理解可用於表示它的最簡單的unicode實體」被解釋爲指的是最小數量的Unicode代碼點。然而,NFC也影響其他事物,例如,用他們的規範等同替換字符。要僅執行*最小化部分,恐怕你必須自己編寫它。 – 2013-05-09 20:20:35