2009-07-24 76 views
19

Tôi gặp sự cố với chuỗi mà tôi nhận được từ một trong các khách hàng của mình trên xmlrpc. Ông gửi cho tôi các chuỗi utf8 được mã hóa hai lần: (vì vậy khi tôi nhận được chúng trong python tôi có một đối tượng unicode đã được giải mã một lần nữa, nhưng rõ ràng là python không cho phép điều đó.Tôi đã nhận thấy khách hàng của tôi tuy nhiên tôi cần làm workaround nhanh chóng cho bây giờ trước khi ông sửa chữa nóGiải mã utf8 được mã hóa đôi trong Python

chuỗi thô từ tcp bãi:.

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

này được chuyển thành:

u'Rafa\xc5\x82' 

Điều tốt nhất chúng tôi nhận được là:

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

Điều này dẫn đến đúng chuỗi đó là:

u'Rafa\u0142' 

này hoạt động tuy nhiên là xấu xí như địa ngục và không thể được sử dụng trong mã sản xuất. Nếu có ai biết cách khắc phục vấn đề này theo cách phù hợp hơn, vui lòng viết. Cảm ơn, Chris

Trả lời

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

@partisann: Gọn gàng! Tôi không biết về raw_unicode_escape (rõ ràng 8-) – RichieHindle

+0

Cảm ơn partisann, tôi không biết về nó. –

+1

Có thể danh tiếng của bạn tăng vượt quá mong đợi, thậm chí sau tất cả những năm đó! :) – Marian

3

Yow, vui quá!

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

Vì vậy, bạn giải mã đầu tiên, nhận chuỗi Unicode trong đó mỗi ký tự thực sự là giá trị byte UTF-8. Bạn đi qua giá trị số nguyên của mỗi ký tự đó để quay lại chuỗi UTF-8 chính hãng, sau đó bạn giải mã như bình thường.

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

latin1 chỉ là từ viết tắt của phương pháp nut'n'bolts của Richie.

Điều rất tò mò là bộ mã hóa raw_unicode_escape nghiêm trọng được mô tả dưới đây cho kết quả tương tự như latin1 trong trường hợp này. Họ luôn đưa ra kết quả tương tự? Nếu vậy, tại sao có một codec như vậy? Nếu không, bạn nên biết chính xác cách khách hàng OP đã thực hiện chuyển đổi từ 'Rafa\xc5\x82' thành u'Rafa\xc5\x82' và sau đó để đảo ngược quy trình đó một cách chính xác - nếu không chúng tôi có thể bị bỏ nếu các dữ liệu khác nhau bị cắt trước khi mã hóa kép được sửa.

+2

Khi chuỗi của bạn chỉ chứa các điểm mã 0-255, nó luôn giống nhau. Sự khác biệt là các ký tự ở trên đó; raw_unicode_escape sẽ thoát chúng, ví dụ như \ u1234, trong đó latin1 sẽ ném UnicodeEncodeError. (Giải mã có sự khác biệt đối xứng - raw_unicode_escape giải mã \ u1234 thoát, latin1 không, nhưng nó chỉ mã hóa ở đây.) Chúng tương đương ở đây, nhưng tôi sẽ gắn với latin1, vì điều này có không có gì để làm với thoát và latin1 là một mã hóa được hiểu rộng rãi hơn. –

+0

Cảm ơn Glenn, suy nghĩ về các dấu gạch chéo ngược sau nửa đêm biến bộ não của tôi thành một quả bí ngô :-) –

Các vấn đề liên quan