在Python 2.7中使用unicodedata.normalize

8

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

u"Cœur"

To

u"Coeur"

我相信使用unicodedata.normalize是解决这个问题的方法,但我无法让它生效。它只会让字符串保持不变。
>>> s = u"Cœur"
>>> unicodedata.normalize('NFKD', s) == s
True

我做错了什么?

3个回答

21

你可以尝试使用Unidecode

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

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

这是一个很棒的答案。简短明了,能够完成任务。 - e h

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

然后,如果您检查两个字符的Unicode参考(您的字符和c + cedila),您会发现后者具有“分解”规范,而前者则缺乏:

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

就像“œ”并非正式等同于“oe”一样 - 至少对于定义此Unicode部分的人来说不是这样 - 因此,规范包含此字符的文本的方法是使用unicode.replace手动替换该字符为序列 - 尽管听起来有些hacky。


其实,我不确定unicodedata.normalize是我想要的。但我找到了一个解决方法。 - dpitch40

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接