字节在一个Unicode的Python字符串中

21 浏览
0 Comments

字节在一个Unicode的Python字符串中

在Python 2中,Unicode字符串可以同时包含Unicode和字节:

a = u'\u0420\u0443\u0441\u0441\u043a\u0438\u0439 \xd0\xb5\xd0\xba'

我知道这绝对不是一个人应该写的代码,但这是一个我必须处理的字符串。

上面字符串中的字节是UTF-8编码的ек(Unicode \u0435\u043a)。

我的目标是获得一个包含所有Unicode字符的Unicode字符串,也就是说Русский ек\u0420\u0443\u0441\u0441\u043a\u0438\u0439 \u0435\u043a)。

将其编码为UTF-8得到:

>>> a.encode('utf-8')
'\xd0\xa0\xd1\x83\xd1\x81\xd1\x81\xd0\xba\xd0\xb8\xd0\xb9 \xc3\x90\xc2\xb5\xc3\x90\xc2\xba'

然后从UTF-8解码得到包含字节的初始字符串,这是不好的:

>>> a.encode('utf-8').decode('utf-8')
u'\u0420\u0443\u0441\u0441\u043a\u0438\u0439 \xd0\xb5\xd0\xba'

我找到了一个解决问题的方法,不过有点hacky:

>>> repr(a)
"u'\\u0420\\u0443\\u0441\\u0441\\u043a\\u0438\\u0439 \\xd0\\xb5\\xd0\\xba'"
>>> eval(repr(a)[1:])
'\\u0420\\u0443\\u0441\\u0441\\u043a\\u0438\\u0439 \xd0\xb5\xd0\xba'
>>> s = eval(repr(a)[1:]).decode('utf8')
>>> s
u'\\u0420\\u0443\\u0441\\u0441\\u043a\\u0438\\u0439 \u0435\u043a'
# 几乎完成了,字节正确了,但之前的真正Unicode字符现在用\u转义了;需要去除转义。
>>> import re
>>> re.sub(u'\\\\u([a-f\\d]+)', lambda x : unichr(int(x.group(1), 16)), s)
u'\u0420\u0443\u0441\u0441\u043a\u0438\u0439 \u0435\u043a' # 成功!

这个方法可以正常工作,但由于使用了evalrepr和额外的正则表达式处理Unicode字符串的表示形式,看起来非常hacky。有没有更简洁的方法?

0