在Python 2中将Unicode字符转换为代码点

时间:2018-04-11 05:45:52

标签: python-2.7 unicode encoding

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

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

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

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

我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

您无法以简单的方式执行此操作:检查ord联机帮助页:https://docs.python.org/2/library/functions.html#ord:python2中仅支持UCS2(因此代码低于65536)。

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

你应该手动计算

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

ADDENDUM:为什么?:

原始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字符,而不是Python3中的1代码点)。上面的代码,使用普通的ord来获取代码点(参数为unicode类型,而不是string类型),但如果它发现第一个字符是代理,则将其翻译(没有额外的检查)。 https://en.wikipedia.org/wiki/UTF-16#U+10000_to_U+10FFFF解释了计算结果。注意:Unicode指定代理代码永远不会被分配为代码点,因此上面的函数对于普通的UCS2也应该是安全的。

你应该调整代码,扫描一个字符串(一些字符放在一个unicode(作为python2类型)字符,一些字符放在两个字符中。

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