2009-07-24 91 views
19

我遇到了一个字符串问题,我通过xmlrpc从我的一个客户端获得了字符串。他向我发送了编码两次的utf8字符串:(所以当我在python中获得它们时,我有一个unicode对象需要再次解码,但显然python不允许这样做。到现在他修正它之前做快速的解决方法在Python中解码双重编码的utf8

从TCP转储原始字符串:

<string>Rafa\xc3\x85\xc2\x82</string> 

这个被转换成:

u'Rafa\xc5\x82' 

我们得到的最好的是:

eval(repr(u'Rafa\xc5\x82')[1:]).decode("utf8") 

这导致正确的字符串是:

u'Rafa\u0142' 

这工作然而这丑陋的地狱,并且不能在生产代码中使用。 如果有人知道如何以更合适的方式解决这个问题,请写。 谢谢, 克里斯

回答

38
 
>>> s = u'Rafa\xc5\x82' 
>>> s.encode('raw_unicode_escape').decode('utf-8') 
u'Rafa\u0142' 
>>> 
+1

@partisann:整洁!我不知道raw_unicode_escape(显然8-) – RichieHindle 2009-07-24 13:17:42

+0

谢谢partisann,我也不知道它。 – 2009-07-27 09:10:47

3

佑,这很有趣!

>>> original = "Rafa\xc3\x85\xc2\x82" 
>>> first_decode = original.decode('utf-8') 
>>> as_chars = ''.join([chr(ord(x)) for x in first_decode]) 
>>> result = as_chars.decode('utf-8') 
>>> result 
u'Rafa\u0142' 

所以你做第一次解码,得到一个Unicode字符串,其中每个字符实际上是一个UTF-8字节值。你通过每个字符的整数值返回到一个真正的UTF-8字符串,然后你就可以正常解码。

2
>>> weird = u'Rafa\xc5\x82' 
>>> weird.encode('latin1').decode('utf8') 
u'Rafa\u0142' 
>>> 

latin1只是Richie's nuts'n'bolts方法的缩写。

非常好奇,在这种情况下,严重不足描述的raw_unicode_escape编解码器给出与latin1相同的结果。他们总是给出相同的结果吗?如果是这样,为什么有这样的编解码器?如果不是,那么最好确切地知道OP的客户端是如何从'Rafa\xc5\x82'u'Rafa\xc5\x82'转换的,然后准确地反转这个过程 - 否则如果在双重编码修复之前不同的数据出现,那么我们可能会解散。