再一次,我对一个 unicode 问题感到非常困惑。我不知道如何成功使用unicodedata.normalize按预期转换非 ASCII 字符。例如,我想转换字符串
u"Cœur"
到
u"Coeur"
我很确定 unicodedata.normalize 是这样做的方法,但我无法让它工作。它只是保持字符串不变。
>>> s = u"Cœur"
>>> unicodedata.normalize('NFKD', s) == s
True
我究竟做错了什么?
再一次,我对一个 unicode 问题感到非常困惑。我不知道如何成功使用unicodedata.normalize按预期转换非 ASCII 字符。例如,我想转换字符串
u"Cœur"
到
u"Coeur"
我很确定 unicodedata.normalize 是这样做的方法,但我无法让它工作。它只是保持字符串不变。
>>> s = u"Cœur"
>>> unicodedata.normalize('NFKD', s) == s
True
我究竟做错了什么?
你可以试试Unidecode
:
# -*- coding: utf-8 -*-
from unidecode import unidecode # $ pip install unidecode
print(unidecode(u"Cœur"))
# -> Coeur
您的问题似乎与 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 部分的人来说不是) - 所以,规范化包含它的文本的方法是手动替换 char 为带有 unicode.replace 的序列 - 听起来很老套。
正如 jsbueno 所说,有些字母只是没有兼容性分解。
您可以使用Unicode CLDR Latin-ASCII 转换来生成手动替换的映射。