规范化Unicode

mic*_*yer 57 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']
Run Code Online (Sandbox Code Playgroud)

但现在:

>>> char = "a?"
>>> len(char)
2
>>> [ unicodedata.name(c) for c in char ]
['LATIN SMALL LETTER A', 'COMBINING ACUTE ACCENT']
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ers 85

unicodedata模块提供了一个.normalize()功能,您想要标准化为NFC格式:

>>> unicodedata.normalize('NFC', u'\u0061\u0301')
u'\xe1'
>>> unicodedata.normalize('NFD', u'\u00e1')
u'a\u0301'
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

请注意,无法保证合成和分解形式具有交际性; 将组合字符规范化为NFC形式,然后将结果转换回NFD形式并不总是产生相同的字符序列.Unicode标准维护一个例外列表 ; 由于各种原因,此列表中的字符是可组合的,但不能分解为它们的组合形式.另请参阅组合物排除表上的文档.


SLa*_*aks 7

是的,有.

unicodedata.normalize(form, unistr)
Run Code Online (Sandbox Code Playgroud)

您需要选择四种规范化形式中的一种.