如何在 Python 中将代理对转换为普通字符串?

这是Converting to Emoji的后续。在那个问题中,OP 有一个json.dumps()-encoded 文件,其中的表情符号表示为代理对 - \ud83d\ude4f。他/他在读取文件和正确翻译表情符号时遇到问题,正确答案是json.loads()文件中的每一行,json模块将处理从代理对转换回(我假设是 UTF8 编码的)表情符号。

所以这是我的情况:假设我只有一个普通的 Python 3 unicode 字符串,其中包含一个代理对:

emoji = "This is \ud83d\ude4f, an emoji."
如何处理此字符串以从中获取表情符号的表示?我希望得到这样的东西:

"This is ?, an emoji."
# or
"This is \U0001f64f, an emoji."
我试过了:

print(emoji)
print(emoji.encode("utf-8")) # also tried "ascii", "utf-16", and "utf-16-le"
json.loads(emoji) # and `.encode()` with various codecs
通常我会收到类似于UnicodeEncodeError: XXX codec can't encode character '\ud83d' in position 8: surrogates no allowed.

我在 Linux 上运行 Python 3.5.1,$LANG设置为en_US.UTF-8. 我已经在命令行的 Python 解释器中和在 Sublime Text 中运行的 IPython 中运行了这些示例 - 似乎没有任何区别。

已邀请:
您已将\ud83d磁盘上的 json 文件中的文字字符串(六个字符: \ u d 8 3 d)和内存中的单个字符u'\ud83d'(使用 Python 源代码中的字符串文字指定)混合在一起。这是Python 3len(r'\ud83d') == 6和len('\ud83d') == 1Python 3 上的区别。

如果您看到'\ud83d\ude4f'Python 字符串(2 个字符),则上游存在错误。通常,你不应该得到这样的字符串。如果你得到一个并且你不能修复产生它的上游;您可以使用surrogatepass错误处理程序修复它:

>>> "\ud83d\ude4f".encode('utf-16', 'surrogatepass').decode('utf-16')
'?'
Python 2 更为宽松。

注意:即使您的 json 文件包含文字 \ud83d\ude4f(12 个字符);你不应该得到代理对:

>>> print(ascii(json.loads(r'"\ud83d\ude4f"')))
'\U0001f64f'
注意:结果是1 个字符 ( '\U0001f64f'),而不是代理对 ( '\ud83d\ude4f')。

要回复问题请先登录注册