python - 规范化 Unicode

标签 python unicode python-3.x

在 Python 中是否有标准方法来规范化 unicode 字符串,以便它只理解可用于表示它的最简单的 unicode 实体?

我的意思是,可以将 ['LATIN SMALL LETTER A', 'COMBINING ACUTE ACCENT'] 之类的序列翻译成 ['LATIN SMALL LETTER A WITH ACUTE']?

看看问题出在哪里:

>>> import unicodedata
>>> char = "á"
>>> len(char)
1
>>> [ unicodedata.name(c) for c in char ]
['LATIN SMALL LETTER A WITH ACUTE']

但是现在:

>>> char = "á"
>>> len(char)
2
>>> [ unicodedata.name(c) for c in char ]
['LATIN SMALL LETTER A', 'COMBINING ACUTE ACCENT']

当然,我可以遍历所有字符并进行手动替换等,但效率不高,而且我很确定我会错过一半的特殊情况并犯错误。

最佳答案

unicodedata 模块提供 .normalize() function ,您想规范化为 NFC 形式。使用相同 U+0061 LATIN SMALL LETTER - U+0301 A COMBINING ACUTE ACCENT 组合和 U+00E1 LATIN SMALL LETTER A WITH ACUTE 的示例> 您使用的代码点:

>>> print(ascii(unicodedata.normalize('NFC', '\u0061\u0301')))
'\xe1'
>>> print(ascii(unicodedata.normalize('NFD', '\u00e1')))
'a\u0301'

(我在这里使用了 ascii() function 以确保使用转义语法打印非 ASCII 代码点,从而明确差异)。

NFC,或“Normal Form Composed”返回组合字符,NFD,“Normal Form Decomposed”为您提供分解的组合字符。

附加的 NFKC 和 NFKD 形式处理兼容性代码点;例如U+2160 ROMAN NUMERAL ONE 实际上与 U+0049 LATIN CAPITAL LETTER I 相同,但存在于 Unicode 标准中以保持与分别处理它们的编码兼容。使用 NFKC 或 NFKD 形式,除了组合或分解字符外,还将所有“兼容”字符替换为其规范形式。

这是一个使用 U+2167 ROMAN NUMERAL EIGHT 代码点的示例;使用 NFKC 形式将其替换为 ASCII VI 字符序列:

>>> unicodedata.normalize('NFC', '\u2167')
'Ⅷ'
>>> unicodedata.normalize('NFKC', '\u2167')
'VIII'

请注意,不能保证组合形式和分解形式是可交换的;将组合字符规范化为 NFC 形式,然后将结果转换回 NFD 形式并不总是会产生相同的字符序列。 Unicode 标准 maintains a list of exceptions ;由于各种原因,此列表中的字符是可组合的,但不能分解回它们的组合形式。另请参阅 Composition Exclusion Table 上的文档。 .

关于python - 规范化 Unicode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16467479/

相关文章:

java - 为什么 `Pattern.compile("(? :\u00e9 )",Pattern.CANON_EQ)` throw?

python - 在 Python 中使用 -q 标志

python - 使用fastapi下载文件

python - Opencv相机崩溃,退出代码-1073741819(0xC0000005)

python - 使用 python 从 dynamoDB 获取项目的唯一值

python - 从python中的unicode字符串获取字节

python - 如何根据我的项目结构访问应用程序上下文之外的 flask 配置变量?

python - Kivy:如何让外部库工作?

python - Snakemake 将多个命令行集成在一个规则中

c# - C# 中的 MySQL utf8_general_ci