8

再一次,我对一个 unicode 问题感到非常困惑。我不知道如何成功使用unicodedata.normalize按预期转换非 ASCII 字符。例如,我想转换字符串

u"Cœur"

u"Coeur"

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

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

我究竟做错了什么?

4

3 回答 3

21

你可以试试Unidecode

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

print(unidecode(u"Cœur"))
# -> Coeur
于 2012-10-18T04:28:15.953 回答
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 部分的人来说不是) - 所以,规范化包含它的文本的方法是手动替换 char 为带有 unicode.replace 的序列 - 听起来很老套。

于 2012-10-17T23:32:57.637 回答
3

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

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

于 2012-10-18T04:10:36.417 回答