2009-07-24 21 views
19

Ho un problema con le stringhe che ottengo da uno dei miei client su xmlrpc. Mi manda utf8 stringhe che sono codificate due volte :(così quando le ottengo in python ho un oggetto unicode che deve essere decodificato ancora una volta, ma ovviamente python non lo permette.ho notato il mio client comunque ho bisogno fare soluzione rapida per il momento prima che lui la fissaDecodifica utf8 con doppia codifica in Python

stringa crudo di discarica tcp:.

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

questo viene convertito in:

u'Rafa\xc5\x82' 

Il meglio che otteniamo è:

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

Ciò si traduce in corretta stringa che è:

u'Rafa\u0142' 

questo funziona però è brutto come l'inferno e non può essere utilizzato nel codice di produzione. Se qualcuno sa come risolvere questo problema in modo più adatto, scrivere. Grazie, Chris

risposta

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

@partisann: Neat! Non sapevo raw_unicode_escape (ovviamente 8-) – RichieHindle

+0

Grazie partisann, non ne sono a conoscenza nemmeno. –

+1

Possa la tua reputazione superare le aspettative, anche dopo tutti questi anni! :) – Marian

3

Yow, che è stato divertente!

>>> 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' 

Così si esegue la prima decodifica, ottenendo una stringa Unicode in cui ogni carattere è in realtà un valore di byte UTF-8. Si passa attraverso il valore intero di ciascuno di questi caratteri per tornare a una vera stringa UTF-8, che poi decodificare come di consueto.

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

latin1 è solo un'abbreviazione per il metodo nuts'n'bolts di Richie.

È molto curioso che il codec raw_unicode_escape seriamente descritto dia lo stesso risultato di latin1 in questo caso. Danno sempre lo stesso risultato? Se è così, perché avere un tale codec? In caso contrario, sarebbe preferibile sapere con certezza esattamente come il client dell'OP ha effettuato la trasformazione da 'Rafa\xc5\x82' a u'Rafa\xc5\x82' e quindi per invertire esattamente tale processo, altrimenti potremmo scollarci se si verificano dati diversi prima della correzione della doppia codifica.

+2

Quando la stringa contiene solo i punti codificati 0-255, è sempre la stessa.Le differenze sono caratteri al di sopra di questo; raw_unicode_escape le sfuggirà, ad es. \ u1234, dove latin1 genererà UnicodeEncodeError. (La decodifica ha la differenza simmetrica - decodifica raw_unicode_escape \ u1234 scappa, latin1 no, ma è solo la codifica qui.) Sono equivalenti qui, ma io rimango con latin1, poiché questo ha niente a che fare con l'escape e latin1 è una codifica più diffusa. –

+0

Grazie Glenn, pensare ai backslash dopo mezzanotte ha trasformato il mio cervello in una zucca :-) –

Problemi correlati