规范化Unicode

时间:2013-05-09 17:21:56

标签: python unicode python-3.x

在Python中是否有标准方法来规范化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']

当然,我可以迭代所有字符并进行手动替换等,但效率不高,而且我很确定我会错过一半的特殊情况,并且会犯错误。

2 个答案:

答案 0 :(得分:76)

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(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标准maintains a list of exceptions;由于各种原因,此列表中的字符是可组合的,但不能分解为它们的组合形式。另请参阅Composition Exclusion Table上的文档。

答案 1 :(得分:6)

Yes, there is

unicodedata.normalize(form, unistr)

您需要选择四个normalization forms中的一个。