首页 > 解决方案 > Python unicode 重音 (à) 十六进制

问题描述

我有一个来自 bs4 的字符串

s = "vinili-disponibili/311-canzoniere-del-lazio-lassa-st\u00c3\u00a0-la-me-creatura.html"

\u00c3\u00a0应该是重音a(à)我已经让它在控制台中部分正确显示为

vinili-disponibili/311-canzoniere-del-lazio-lassa-stà-la-me-creatura.html

str2 = u'%s' % s
print(str2.encode('utf-8').decode('unicode-escape'))

但它分别解码 c3 和 a0,所以我得到一个波浪号 A 而不是重音 a。我知道 c3 a0 是重音 a 的十六进制 utf-8。我不知道发生了什么,我使用谷歌和我得到的答案的组合方法来到这里。这整个字符编码的事情对我来说似乎是一团糟。

它应该是这样的

311-canzoniere-del-lazio-lassa-stà-la-me-creatura.html

编辑:安德烈的方法在打印出来时有效,但试图将 urlopen 与我得到的字符串一起使用UnicodeEncodeError: 'ascii' codec can't encode character '\xe0' in position 60: ordinal not in range(128)

使用后unquote(str,":/")给出UnicodeEncodeError: 'ascii' codec can't encode characters in position 56-57: ordinal not in range(128).

标签: pythonunicodecharacter-encoding

解决方案


假设 Python 2:

这是一个带有 Unicode 转义的字节字符串。为某些 UTF-8 编码的数据错误地生成了 Unicode 转义:

>>> s = "vinili-disponibili/311-canzoniere-del-lazio-lassa-st\u00c3\u00a0-la-me-creatura.html"
>>> s.decode('unicode-escape')
u'vinili-disponibili/311-canzoniere-del-lazio-lassa-st\xc3\xa0-la-me-creatura.html'

现在它是一个 Unicode 字符串,但现在出现错误解码,因为代码点类似于 UTF-8 字节。它转而输出latin1(也是iso-8859-1)编解码器将前 256 个代码点直接映射到字节 0-255,因此使用此技巧将其转换回字节字符串:

>>> s.decode('unicode-escape').encode('latin1')
'vinili-disponibili/311-canzoniere-del-lazio-lassa-st\xc3\xa0-la-me-creatura.html'

现在它可以正确解码为 UTF-8:

>>> s.decode('unicode-escape').encode('latin1').decode('utf8')
u'vinili-disponibili/311-canzoniere-del-lazio-lassa-st\xe0-la-me-creatura.html'

它是一个 Unicode 字符串,因此 Python 显示它的repr()值,将 U+007F 以上的代码点显示为转义码。 print假设您的终端正确配置了支持打印字符的编码,它会查看实际值:

>>> print(s.decode('unicode-escape').encode('latin1').decode('utf8'))
vinili-disponibili/311-canzoniere-del-lazio-lassa-stà-la-me-creatura.html

理想情况下,首先解决错误生成此字符串的问题,而不是解决混乱问题。


推荐阅读