Mor*_*uhr 12 python unicode utf-8
我正在努力反对一个似乎热衷于返回的应用程序,我认为是双UTF-8编码的字符串.
我发送u'XüYß'使用UTF-8编码的字符串,从而变为X\u00fcY\u00df(等于X\xc3\xbcY\xc3\x9f).
服务器应该简单地回显我发送的内容,但返回以下内容:( X\xc3\x83\xc2\xbcY\xc3\x83\xc2\x9f应该是X\xc3\xbcY\xc3\x9f).如果我对其进行解码使用str.decode('utf-8')变u'X\xc3\xbcY\xc3\x9f',它看起来像一个......的unicode字符串,使用含UTF-8编码的原始字符串.
但Python不会让我解码unicode字符串而不首先重新编码它 - 由于某种原因失败了,这让我感到厌烦:
>>> ret = 'X\xc3\x83\xc2\xbcY\xc3\x83\xc2\x9f'.decode('utf-8')
>>> ret
u'X\xc3\xbcY\xc3\x9f'
>>> ret.decode('utf-8')
# Throws UnicodeEncodeError: 'ascii' codec can't encode ...
Run Code Online (Sandbox Code Playgroud)
我如何说服Python重新解码字符串?- 和/或是否有任何(实用的)方法来调试字符串中的实际内容,而不通过所有隐式转换print使用它?
(是的,我已经向服务器端的开发人员报告了这种行为.)
小智 23
ret.decode()隐式尝试ret使用系统编码进行编码 - 在您的情况下为ascii.
如果你明确编码unicode字符串,你应该没问题.有一个内置编码,可以满足您的需求:
>>> 'X\xc3\xbcY\xc3\x9f'.encode('raw_unicode_escape').decode('utf-8')
'XüYß'
Run Code Online (Sandbox Code Playgroud)
真的,.encode('latin1')(或cp1252)会没问题,因为这就是服务器几乎不能使用的东西.该raw_unicode_escape编解码器将只是给你的东西识别在最后,而不是抛出一个异常:
>>> '€\xe2\x82\xac'.encode('raw_unicode_escape').decode('utf8')
'\\u20ac€'
>>> '€\xe2\x82\xac'.encode('latin1').decode('utf8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'latin-1' codec can't encode character '\u20ac' in position 0: ordinal not in range(256)
Run Code Online (Sandbox Code Playgroud)
如果您遇到这种混合数据,您可以再次使用编解码器来规范化所有内容:
>>> '€\xe2\x82\xac'.encode('raw_unicode_escape').decode('utf8')
'\\u20ac€'
>>> '\\u20ac€'.encode('raw_unicode_escape')
b'\\u20ac\\u20ac'
>>> '\\u20ac€'.encode('raw_unicode_escape').decode('raw_unicode_escape')
'€€'
Run Code Online (Sandbox Code Playgroud)