在 Python 2.7 中使用 unicodedata.normalize

Posted

技术标签:

【中文标题】在 Python 2.7 中使用 unicodedata.normalize【英文标题】:Using unicodedata.normalize in Python 2.7 【发布时间】:2012-10-08 07:44:26 【问题描述】:

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

u"Cœur"

u"Coeur"

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

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

我做错了什么?

【问题讨论】:

【参考方案1】:

你可以试试Unidecode:

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

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

【讨论】:

这是一个很好的答案。简短而简单,可以完成工作。【参考方案2】:

您的问题似乎与 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.htmhttp://www.fileformat.info/info/unicode/char/00e7/index.htm

就像“œ”在形式上并不等同于“oe”——(至少对于定义这个 unicode 部分的人来说不是)——所以,规范化包含它的文本的方法是手动替换用 unicode.replace 表示序列的字符 - 听起来很老套。

【讨论】:

实际上,我不确定 unicodedata.normalize 是我想要的。但我确实想出了一个解决方法。【参考方案3】:

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

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

【讨论】:

以上是关于在 Python 2.7 中使用 unicodedata.normalize的主要内容,如果未能解决你的问题,请参考以下文章

有效地将字符串转换为 python 2.7 的 unicode

python 使用``subprocess.Popen``修复python 2.7 windows unicode问题。

Python 2.7:如何将字符串中的 unicode 转义转换为实际的 utf-8 字符

关于在2.7中出现 "UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode

在 Python 2.7 中使用 unicodedata.normalize

在 python 3 和 2 中工作的 Unicode 文字