【问题标题】:different behavior of unicodedata.normalize methodunicodedata.normalize 方法的不同行为
【发布时间】:2019-04-08 03:58:51
【问题描述】:

以下代码取自ThisSO 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 中的字符。为什么我与 normalize 方法调用不一样?

【问题讨论】:

    标签: python unicode-normalization


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢,我刚刚运行print([i for i in unicodedata.normalize('NFD','Ślusàrski')]) 并得到['S', '́', 'l', 'u', 's', 'a', '̀', 'r', 's', 'k', 'i'] 作为输出。你说的对。但是,为什么 python 将前两个字符组合起来作为一个字符打印出来呢?
    • @InAFlash:因为修饰符就是这样工作的;他们的全部交易是在打印时它们与前一个字符结合在一起。
    • 哦,非常感谢。所以,我只需要把它列成一个列表并删除这些字符。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 1970-01-01
    • 2010-10-26
    • 2011-02-18
    • 2012-11-12
    • 2018-08-20
    • 2016-10-31
    相关资源
    最近更新 更多