2009-07-24 14 views
19

Müşterilerimden xmlrpc üzerinden aldığım dizelerle ilgili bir sorunum var. Bana iki kere kodlanmış utf8 dizeleri gönderir: (python'a aldığımda, bir kez daha çözülmemesi gereken bir unicode nesneye sahibim, ama açıkça python buna izin vermez. İstemcimi farkettim ancak şimdi o düzeltir önce çabuk geçici çözümüPython'da çift kodlanmış utf8 kod çözme

tcp dökümü gelen

Ham dize .

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

bu dönüştürülür: aldığımız iyi

u'Rafa\xc5\x82' 

geçerli:

Bu ancak çalıştığı cehennem gibi çirkin ve üretim kodunda kullanılamaz

u'Rafa\u0142' 

:

Bu doğru dize ile sonuçlanır. Bu sorunu daha uygun bir şekilde nasıl düzelteceğini bilen varsa lütfen yazınız. sayesinde Chris

cevap

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

@partisann: Neat! Raw_unicode_escape hakkında birşey bilmiyordum (açıkçası 8-) – RichieHindle

+0

Teşekkürler partisann, ben de bilmiyordum. –

+1

İtibarınız, o yıllardan sonra bile beklentinizin ötesine geçebilir! :) – Marian

3

YOW Bu eğlenceliydi!

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

Yani her karakter aslında bir UTF-8 bayt değeridir Unicode dizesi alma, ilk kod çözmeyi yapmak. Bu karakterlerin her birinin tamsayı değeri üzerinden gerçek bir UTF-8 dizesine geri dönersiniz, daha sonra normal olarak kodunu çözersiniz.

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

latin1 Richie's nuts'n'bolts yönteminin bir kısaltmasıdır.

Bu durumda ciddi olarak az bilinen raw_unicode_escape kodekinin latin1 ile aynı sonucu vermesi çok meraklıdır. Her zaman aynı sonucu veriyorlar mı? Eğer öyleyse, neden böyle bir kodek var? Aksi halde, OP'nin müşterisinin 'Rafa\xc5\x82' - u'Rafa\xc5\x82' arasındaki dönüşümü tam olarak nasıl yaptığını bilmek ve daha sonra bu işlemi tam tersine çevirmek tercih edilirdi. Aksi takdirde, çift kodlamadan önce farklı veriler kesilirse, geri çekilebiliriz.

+2

Dize, yalnızca 0-255 kod noktalarını içerdiğinde, her zaman aynıdır. Farklar yukarıdaki karakterlerin üzerindedir: raw_unicode_escape onları, örneğin. latin1 UnicodeEncodeError'ı atar. u1234, (kod çözme simetrik bir farka sahiptir - raw_unicode_escape kod çözücüleri \ u1234 kaçar, latin1 yapmaz, ama sadece burada kodlama yapar.) Burada eşdeğerdirler, ama latin1 ile yapışırdım Kaçış ve latin1 ile ilgisi olmayan bir şey daha yaygın olarak anlaşılan bir kodlamadır. –

+0

Teşekkürler Glenn, gece yarısından sonra ters eğiklikleri düşünerek beynimi balkabağına çevirdi :-) –