python - 将包含 utf-8 编码的字节串和代码点的字符串转换为 utf-8 编码的字符串

标签 python unicode encoding utf-8

我从 API 得到一个 JSON 响应,如下所示:

{"excerpt":"...where we\u00e2\u0080\u0099ll just have to wait and see, I\u00e2\u0080\u0099m sure official announcements with start flowing in the coming months \u2013special\u2013..."}

这是从 API 调用返回的原始 JSON 响应。现在,如您所见,JSON 文档中有代码点,这是传输 unicode 数据时应该有的代码点。但是 API 响应返回了错误的代码点,因为“摘录”在该摘录所属的原始来源中以“... where we'll ...”开头。如您所见,\u00e2\u0080\u0099 序列用于表示 ’ -右单引号- 字符,但该字符的代码点实际上是\u2019,而编码为 utf-8 的等效字节串是\xe2\x80\x99。所以它返回各自的字节串而不是代码点。另一个问题是这个响应包含正确的代码点,就像之前的响应中的\u2013(破折号字符)一样,这使我的代码无法处理这两种情况。

我最终必须从此响应中获取一些字段(可能使用 json.loads 并将\u00e2\u0080\u0099 转换为\xe2\x80\x99 但对\u2013 没有任何作用),连接这些字段并发送结果到另一个库,该库最终使用 urllib.urlencode 将该结果编码为有效的 utf-8 url 参数,以便将其发送到另一个 API。

所以这是我的问题:有没有一种方法可以将同时包含 utf-8 字节串和 unicode 代码点(这是执行 json.loads 的结果)的字符串编码为另一个仅包含代码点或 utf-8 字节串的字符串所以我可以在 urllib.urlencode 中使用它,或者在执行 json.loads 之前可能有解决方案? 注意:我使用的是 Python 2.6.1

我已经联系了 API 所有者并通知他们他们应该使用有效的代码点而不是字节串,但我不确定他们什么时候会联系我所以我正在尝试针对当前情况提出解决方案。

我们将不胜感激。

最佳答案

您可以使用正则表达式来识别“类似 UTF-8”的 Unicode 序列并将它们处理成正确的 Unicode 字符:

import re
D = {"excerpt":"...where we\u00e2\u0080\u0099ll just have to wait and see, I\u00e2\u0080\u0099m sure official announcements with start flowing in the coming months \u2013special\u2013..."}
s = D['excerpt']
print s
s = s.decode('unicode-escape')
print s
print re.sub(ur'[\xc2-\xf4][\x80-\xbf]+',lambda m: m.group(0).encode('latin1').decode('utf8'),s)

输出:

...where we\u00e2\u0080\u0099ll just have to wait and see, I\u00e2\u0080\u0099m sure official announcements with start flowing in the coming months \u2013special\u2013...
...where weâll just have to wait and see, Iâm sure official announcements with start flowing in the coming months –special–...
...where we’ll just have to wait and see, I’m sure official announcements with start flowing in the coming months –special–...

更新...

根据您的评论,字典已经是一个 Unicode 字符串,因此\u2013 字符可以正确打印(请参阅下面的第一个打印输出),因此可以跳过 decode('unicode-escape')re.sub 语句仍然有效:

import re
D = {u'excerpt':u'...where we\xe2\x80\x99ll just have to wait and see, I\xe2\x80\x99m sure official announcements with start flowing in the coming months \u2013special\u2013...'}
s = D[u'excerpt']
print s
print re.sub(ur'[\xc2-\xf4][\x80-\xbf]+',lambda m: m.group(0).encode('latin1').decode('utf8'),s)

输出:

...where weâll just have to wait and see, Iâm sure official announcements with start flowing in the coming months –special–...
...where we’ll just have to wait and see, I’m sure official announcements with start flowing in the coming months –special–...

关于python - 将包含 utf-8 编码的字节串和代码点的字符串转换为 utf-8 编码的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5842115/

相关文章:

java - Ubuntu/Tomcat 服务器 UTF-8 编码问题

python - 如何在 Python 中序列化哈希对象

python - Unicode 字符串 Python

sql-server - SQL Server Management Studio - 网格结果另存为 .CSV - 如何输出文本而不是 UTF-16 (Unicode)

python - 如何以与 python2 和 python3 一起使用的方式将 utf8 写入标准输出

php - 数据库字符集转换

python - Pytest 日志记录忽略 pytest.ini 中的选项

python - 全屏启动程序 (Python)

Python.el 和 Python 模式 : Documentation & Features

python - 使用 unicode_literals 在 Flask 应用程序中添加 header