Python - 读取 Emoji Unicode 字符

9
我可以为您翻译中文。以下是需要翻译的内容:

我有一个Python 2.7程序,从SQLite数据库中读取iOS短信。这些短信是Unicode字符串。在下面的短信中:

u'that\u2019s \U0001f63b'

撇号用\u2019表示,但表情符号用\U0001f63b表示。我查了一下这个表情符号的代码点,是\uf63b。我不知道0001是从哪里来的。我对字符编码知之甚少。

当我逐个字符打印文本时,使用:

s = u'that\u2019s \U0001f63b'

for c in s:
    print c.encode('unicode_escape')

该程序产生以下输出:
t
h
a
t
\u2019
s

\ud83d
\ude3b

我应该如何在Python中正确读取这些最后的字符?我在这里使用编码正确吗?我应该在读取之前尝试删除那些0001,还是有更简单、不那么愚蠢的方法?

0xf63b位于Unicode的“专用区”中。您确定这是正确的吗?您的代码点可能是0x1f63b,因为那是一个带有心形眼睛的“笑猫”表情符号。 - Alyssa Haroldsen
你是如何确定\uf63b会成为一个Emoji字符的?根据我的参考资料,它是未定义的:http://www.fileformat.info/info/unicode/char/f63b/index.htm - Mark Ransom
2个回答

19

我认为你没有正确使用编码,也不需要这样做。你所拥有的是一个有效的 Unicode 字符串,其中包含一个 4 位和一个 8 位的转义序列。在 OS X 上的 REPL 中尝试一下:

>>> s = u'that\u2019s \U0001f63b'
>>> print s
that’s 

在Python 3中,尽管 -

Python 3.4.3 (default, Jul  7 2015, 15:40:07) 
>>> s  = u'that\u2019s \U0001f63b'
>>> s[-1]
''

看看这个...我真的什么都不知道。谢谢!但是,我仍然不清楚如何读取最后一个字符。s[-1]和s[-2]仍然会给出'\ud83d'和'\ude3b'。有没有一种逐个读取字符串字符的方法? - Andrew LaPrise
1
@alaprise,你看到的是 Python 存储其 Unicode 字符串的内部方式所产生的一个现象。如果你在 Python 3 中做同样的事情,你会看到完全不同的东西。 - Mark Ransom
2
@alaprise 另一个答案提供了一些好的信息,总结起来就是“如果可能,请转向Python3”。否则,你将进入一个痛苦的世界/代理对/你不想知道的单词,因为它们是克苏鲁之歌。 - pvg
1
'\ud83d'和'\ude3b'是代理对,由UTF-16用于表示超过U+FFFF的码点。这是Python 2中的一个错误,在许多语言中都存在这些字符的问题。 - roeland
显示剩余2条评论

3

你的困惑可能是因为你正在运行所谓的“窄Python构建”。Python 无法容纳足够信息来保存单个表情符号。最好的解决方案是转换到 Python 3。否则,尝试处理UTF-16代理对


可以使用 regex.findall(r'\X', unicode_text) 来获取“用户感知字符”,这些字符可能跨越多个 Unicode 代码点(它与代理对无关,但作为副作用应该可以解决此问题)。 - jfs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接