unicodedata.decomposition() 与 unicodedata.normalize(NFD/NFKD)?

问题描述 投票:0回答:2

根据 py3 doc

  • unicodedata.分解(chr)

    以字符串形式返回分配给字符

    chr
    的字符分解映射。空字符串是 如果未定义此类映射,则返回。

这里我不太明白字符分解映射是如何定义的以及

unicodedata.decomposition()
unicodedata.normalize(NFD/NFKD)
之间的关系/区别是什么?

请参阅以下示例:

$ python3
>>> import unicodedata
>>> unicodedata.decomposition('⑴')
'<compat> 0028 0031 0029'              <-- why not just '0028 0031 0029'?
>>> unicodedata.normalize('NFKD', '⑴')
'(1)'
>>> unicodedata.decomposition('①')
'<circle> 0031'                        <-- why not just '0031'?
>>> unicodedata.normalize('NFKD', '①')
'1'
>>> unicodedata.decomposition('è')
'0065 0300'                            <-- like this?
>>> unicodedata.normalize('NFD', 'è') == '\u0065\u0300'
True
>>>
python python-3.x unicode python-unicode
2个回答
3
投票

unicodedata.decomposition
返回单个代码点Unicode 字符数据库中使用的格式的分解类型和映射。来自 UAX #44:

Decomposition_Type、Decomposition_Mapping:该字段包含两个值,类型位于尖括号中。

如果尖括号中没有类型,则代码点具有 NFC 和 NFD 中使用的“规范分解”。如果尖括号中有类型,则代码点具有 兼容性分解,除了规范分解之外,NFKC 和 NFKD 也会使用该分解。

unicodedata.normalize

实现整个字符串的 Unicode 规范化算法。

    


2
投票

K是“兼容性”。 Unicode 必须在 Unicode 中插入一些代码,以便能够进行往返而不丢失信息。 “K”转换将删除此类“额外/不需要的”字符(根据其他规则,这些字符不应出现在 Unicode 中)。

因此,下标数字、上标数字、分数和带圆圈的数字(在您的示例中)都会被转换(它们应该是标准数字+标记格式(在 Unicode 和字符之外)。

问题:使用下标,只能得到数字,因此改变含义,例如

转换为

42
。 K 将删除文本的一些语义(这些语义本来就不应该存在,但仅仅分解还不够好)

所以K不应该被使用,而是用于特定用途。其中一种用途是用于字符串搜索,或者查看一个用户名是否与其他用户名太相似(可能无法区分)[但仅“K”是不够的]。

D 是标准化:D 会将字符分解为组件,因此

ê

会转换为

e
和组合字符
^
。这也是Unicode的目标之一:将所有字符编码为65366个代码是无法实现的,因此字符是组合而成的。 (这在汉字中最为明显)。同样,为了兼容性和往返,添加了一些重音字符,后来 Unicode 扩展到超过 65536 个代码。

因此,我们用 D 表示分解的字符(基本 + 组合代码),用 C 表示更紧凑的符号(如果可用于此类组合)。此外,这些转换在 Unicode 标准中进行了描述(很少有历史特殊情况和“错误”)。

© www.soinside.com 2019 - 2024. All rights reserved.