【问题标题】:Converting Unicode character to codepoint in Python 2在 Python 2 中将 Unicode 字符转换为代码点
【发布时间】:2018-09-20 21:13:45
【问题描述】:

我有一个用 Python 3 编写的模块,其中一个功能是将 unicode 字符转换为代码点(例如,使用 ord('????' 将 ???? 转换为 127921)。

现在我需要转换此代码以使其适用于 Python 2,但 ord() 不适用于具有非 ascii 字符的 Python 2。

我曾尝试使用'????'.encode('utf8') 或'????'.encode('hex'),但无济于事。

查看__futures__ 包,似乎没有帮助。

我在这里错过了什么?

【问题讨论】:

    标签: python-2.7 unicode encoding


    【解决方案1】:

    您不能以简单的方式做到这一点:查看ord 手册页:https://docs.python.org/2/library/functions.html#ord:python2 仅支持 UCS2(因此代码低于 65536)。

    注意:您应该在 unicode 字符串前面加上 u。

    你应该手动计算

    to_decode = u'?'
    code = ord(to_decode[0])
    if code >= 0xd800 and code <= 0xdbff:
        # we have surrogates
        code = (code - 0xd800) * 1024 + (ord(to_decode[1]) - 0xdc00) +  + 0x010000
    

    附录:为什么?:

    最初的 Unicode 设想 16 位编码就足够了(这解释了 Han/Kana(中文/日文)和韩文特殊实现的合并)。这给出了从 0 到 65535 的代码点,通常编码为 UCS2。 Python 2 使用这种编码。

    当注意到 16 位不够用时,Unicode 找到了使用更多位的方法:使用“代理”:使用两个“16 位字符”(第一个“代码”中的 10 位,但在0xD800..0xDBFF,第二个“代码”中的 10 位放入 0xDC00..0xDFFF,并添加 65536(最后一点确保没有双重方式来编码字符(并进一步扩展 unicode 范围)。

    UTF-16 是 UCS2 加上代理项的解释(在 Unicode 中指定)。但是python2使用UCS2。如果你尝试使用len(to_decode),你会得到2(两个代理代码点/UCS2 字符,而不是1 Python3 中的代码点)。上面的代码,使用普通的ord获取代码点(参数为unicode类型而不是string类型),但如果发现第一个字符是代理,则翻译它(无需额外检查)。 https://en.wikipedia.org/wiki/UTF-16#U+10000_to_U+10FFFF 解释计算。注意:Unicode 指定代理代码永远不会被分配为代码点,因此上述函数对于普通 UCS2 也应该是安全的。

    您可能应该修改代码以扫描字符串(有些字符放在一个 unicode(作为 python2 类型)字符中,有些放在两个字符中。

    我建议尽可能使用 Python3:他们修复了 unicode,但没有像在 python2 或其他语言中那样的变通方法(因此容易出错且更复杂)。

    【讨论】:

    • 为什么投反对票?我认为我是对的,所以如果你不解释,我就无法改进。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    • 2011-10-22
    相关资源
    最近更新 更多