在Python 2.7中使用unicodedata.normalize

时间:2012-10-17 22:57:50

标签: python python-2.7 unicode normalization unicode-normalization

再一次,我对unicode问题非常困惑。我无法弄清楚如何成功使用unicodedata.normalize按预期转换非ASCII字符。例如,我想转换字符串

u"Cœur"

u"Coeur"

我很确定unicodedata.normalize是这样做的方法,但我无法让它工作。它只是保持字符串不变。

>>> s = u"Cœur"
>>> unicodedata.normalize('NFKD', s) == s
True

我做错了什么?

3 个答案:

答案 0 :(得分:20)

您可以尝试Unidecode

# -*- coding: utf-8 -*-
from unidecode import unidecode # $ pip install unidecode

print(unidecode(u"Cœur"))
# -> Coeur

答案 1 :(得分:6)

你的问题似乎与Python没有关系,但是你试图分解的角色(u'\ u0153' - 'œ')本身并不是一个组合。

检查您的代码是否使用包含普通复合字符的字符串,例如“ç”和“ã”:

>>> a1 = a
>>> a = u"maçã"
>>> for norm in ('NFC', 'NFKC', 'NFD','NFKD'):
...    b = unicodedata.normalize(norm, a)
...    print b, len(b)
... 
maçã 4
maçã 4
maçã 6
maçã 6

然后,如果你检查两个字符(你的和c + cedila)的unicode引用,你会看到后者有一个前者缺乏的“分解”规范:

http://www.fileformat.info/info/unicode/char/153/index.htm
http://www.fileformat.info/info/unicode/char/00e7/index.htm

它类似于“œ”并不正式等同于“oe” - (至少不适用于定义此unicode部分的人) - 因此,规范化包含此文本的文本的方法是手动替换使用unicode.replace的序列的char - 听起来像hacky。

答案 2 :(得分:3)

正如jsbueno所说,有些字母没有兼容性分解。

您可以使用Unicode CLDR Latin-ASCII transform生成手动替换的映射。