Python 不读取 unicode U + FE0F

Python does not read unicode U + FE0F

假设我将 WhatsApp 聊天导出为 .txt,然后使用 python 阅读它。似乎 python 没有读取包含 \uFE0F 的表情符号的正确 unicode 组合。例如彩虹旗表情符号️‍是U+1F3F3 U+FE0F U+200D U+1F308。但是,如果我使用 python 读取文件,使用下面的代码,标志表情符号将被读取为 \U0001f3f3\u200d\U0001f308。我的代码有问题吗? WhatsApp导出的文件不正确?还是有其他原因造成这种行为?

我想编写一个程序来查找聊天中的所有表情符号,但是 \U0001f3f3\u200d\U0001f308 不是现有的表情符号,所以我现在收到错误...

def showchat():
    f = open("MyChat.txt", "r")
    lines = f.readlines()
    for l in lines:
        print(l)
        print(str(l.encode('unicode-escape')))
    f.close()

WhatsApp 似乎以 UTF-8 格式导出文件。因此,当您 open 文件时,您必须设置该编码:

f = open("MyChat.txt", "r", encoding="utf-8")

可能您的 Python 安装已经默认为 UTF-8,因为当您的程序尝试读取文件时您没有收到错误。由于 '\ufe0f' 是一个不代表实际字符的特殊 Unicode 代码点,因此 WhatsApp 可能无法正确导出它。您需要对文件进行十六进制转储以确定它实际包含的内容。

这是一个老问题,但值得解释一下是怎么回事。问题不是 Python。它甚至可能不是 Whatsapp,它可能是用户用来输入表情符号的键盘软件。


彩虹旗有两种写法。查看来自 Unicode 的 emoji-test.txt 文件(发现 here):

1F3F3 FE0F 200D 1F308                                  ; fully-qualified     # ️‍ E4.0 rainbow flag
1F3F3 200D 1F308                                       ; unqualified         # ‍ E4.0 rainbow flag

第一种方式是您期望的方式,第二种方式是Whatsapp 正在生成的方式。第一种方式是完全合格的,而第二种方式是不合格的。您可以找到这些术语的定义 here,但基本上完全合格意味着包括所有推荐的代码点。在这种情况下,这意味着 FE0F 在那里,它明确告诉渲染器这个表情符号应该以图形方式显示,而不是像 ☺.

这样的文本格式。

不合格的格式实际上不应该出现,键盘永远不应该生成它们。但是几乎所有的渲染器,比如你的浏览器、字体、Whatsapp,都会将它们渲染为表情符号,因为它有助于保持工作正常,看起来不错,以防出现不合格的表情符号。

一般来说,像您这样解析未知输入的软件应该支持表情符号的所有三种变体(完全、最小和不合格),因此您应该更改代码以将这两种彩虹旗表情符号识别为有效。

有关更多信息,您可以查看 Unicode Emoji Implementation Notes, as well as my previous link. You'll also want to know about Zero Width Joiners(如果您还没有的话)。