unicodedata.normalize 方法的不同行为

different behavior of unicodedata.normalize method

以下代码摘自This SO Post.

def unicodeToAscii(s):
    return ''.join(
        c for c in unicodedata.normalize('NFD', s)
        if unicodedata.category(c) != 'Mn'
        and c in all_letters
    )

当我运行这个

print(unicodeToAscii('Ślusàrski'))

我得到以下输出

Slusarski

但是,当我只是 运行 unicodedata.normalize('NFD','Ślusàrski') 时,我得到与输出相同的旧字符串 Ślusàrski

函数中的代码只是做同样的事情,并忽略所有不属于类别 Mn 且属于 all_letters 的字符。为什么我对规范化方法调用不一样?

unicodedata.normalize('NFD','Ślusàrski') 的输出可能看起来 与输入字符串相同,但事实并非如此。如果我们使用 ascii() 强制所有非 ASCII 字符以 \uXXXX 转义显示,我们得到:

>>> print(ascii(unicodedata.normalize('NFD','Ślusàrski')))
'S\u0301lusa\u0300rski'

在这里我们看到了 NFD 的效果:每个重音字符被分解为一个非重音字符加上一个重音字符(类别 Mn)。这就是为什么您的第一个代码片段的其余部分会生成 Slusarski:它不是在 Ś 上运行,而是在 S+´.

上运行