将“\xF0\x9D\x96\xA7\xF0\x9D”转换为 Python 中的 "normal" 字符串

Convert "\xF0\x9D\x96\xA7\xF0\x9D" to "normal" string in Python

(注意,我不是 100% 确定字符串是如何编码的,不同编码方案之间的区别等。因此我可能会在这里问一个愚蠢的问题。我使用 VScode 作为 IDE 和 Python 3.8.1)

我 运行 今天遇到了一个问题,一位客户给我们发了一封电子邮件。我已经从 Zendesk 的 API 中提取了电子邮件,并希望将其存储在我们的 MySQL 数据库中。我在推送时收到此 incorrect string value '\xF0\x9D\x96\xA7\xF0\x9D' 错误,这很奇怪,因为电子邮件正文只是纯文本,如 Hello - where is my package?(另一种语言)。过了一会儿,我注意到所有字母看起来都不像“普通字符串字母”,结果发现电子邮件中的 Hello 不等于 "Hello"email_body[:5]=="Hello" 是假的(也许电子邮件中使用了一些奇怪的字体?)。对正文进行编码显示,正文确实以 \xF0\x9D\x96\xA7\xF0\x9D 开头,而不是“Hello”

问题是,如上所示,邮件中的 "Hello" 不等于“普通”"Hello" 因此我无法比较字符串、进行字符串操作等。

有没有办法把我从邮件正文中得到的“Hello”转换成普通字符串,这样两个“Hello”字符串又相等了?

正如评论中提到的,该字符串以 Unicode 字符 U+15AD7 MATHEMATICAL SANS-SERIF CAPITAL H 开头,它看起来像一个普通的 H,但实际上是一个不同的字符。

来自 MySQL 的错误消息可能是由于您的 MySQL table 使用 utf8 编码而不是 utf8mb4。后者需要存储基本多语言平面之外的 Unicode 字符(代码点大于 0xFFFF)。

您可以将 U+15AD7 MATHEMATICAL SANS-SERIF CAPITAL H 转换为 U+0048 LATIN CAPITAL LETTER H,方法是使用 NFKC 等兼容性规范化形式进行规范化,但这不会解决底层数据库问题:

import unicodedata
s = b"\xF0\x9D\x96\xA7".decode()
n = unicodedata.normalize('NFKC', s)
print(n, '%04x'%ord(n))  # Should print "H 0048"