将“\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"
(注意,我不是 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"