2017-11-16 325 views
10

Öncelikle sorunu tanıtmama izin verin.Python 3'ün Dönüştürülmesi Unicode - `str (utf8_encoded_str) 'nin bir bayt dizisi unicode'a geri dön

POST/GET istekleri aracılığıyla bazı verilerim var. Veriler UTF-8 kodlu dizgiydi. Bunu az biliyordum ve sadece str() yöntemiyle dönüştürdüm. Ve şimdi "saçma veri" tam veritabanı var ve geri bir yol bulamadık.

örnek kod:

unicode_str - Bu ben

encoded_str alması gerekmektedir dizedir - bu benim POST/GET istekleri ile var dizedir - ilk veri

bad_str - Veritabanında şu anda sahip olduğum veriler ve unicode almam gerekiyor.

Yani dönüştürme bilmek görünüşte: : = (encode) =>encoded_str = (str) =>bad_str

Ama geri çözüm ile gelebilir değil unicode_str bad_str = (???) =>encoded_str = (decode) =>

unicode_str
In [1]: unicode_str = 'Příliš žluťoučký kůň úpěl ďábelské ódy' 

In [2]: unicode_str 
Out[2]: 'Příliš žluťoučký kůň úpěl ďábelské ódy' 

In [3]: encoded_str = unicode_str.encode("UTF-8") 

In [4]: encoded_str 
Out[4]: b'P\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88 \xc3\xbap\xc4\x9bl \xc4\x8f\xc3\xa1belsk\xc3\xa9 \xc3\xb3dy' 

In [5]: bad_str = str(encoded_str) 

In [6]: bad_str 
Out[6]: "b'P\\xc5\\x99\\xc3\\xadli\\xc5\\xa1 \\xc5\\xbelu\\xc5\\xa5ou\\xc4\\x8dk\\xc3\\xbd k\\xc5\\xaf\\xc5\\x88 \\xc3\\xbap\\xc4\\x9bl \\xc4\\x8f\\xc3\\xa1belsk\\xc3\\xa9 \\xc3\\xb3dy'" 

In [7]: new_encoded_str = some_magical_function_here(bad_str) ??? 

cevap

11

Bayt nesnesini, yalnızca bayt nesnesinin bir temsili olan bir dizeye çevirdiniz. Özgün bayt nesnesini ast.literal_eval() (öneri için Mark Tolonen için krediler) kullanarak edinebilirsiniz, daha sonra basit bir decode() işi yapacak.

güvende olacağını eval() kullanarak dizeleri oluşturulan, ama neden olmasın daha güvenli sendin yana
>>> import ast 
>>> ast.literal_eval(bad_str).decode('utf-8') 
'Příliš žluťoučký kůň úpěl ďábelské ódy' 

?

+0

iyi, ben 'akılda da eval' vardı, ama orada hangi verilerin olduğunu ben biliyorum olmadığı ve çok fazla veri var, öyleydim Bundan kaçınmak umuduyla - bundan bahsetme. Ama teşekkürler :) – darkless

+4

@darkless Kaydedilen dizelerin neye benzediği önemli değil. Utf-8 dizesini alma prosedürünü takip ettiğiniz sürece -> bir bytes nesnesine kodlayın -> bu ** 'yi bir dizgeye dönüştürün ve veritabanınıza depolayın, bu dizeleri zararsız bayt nesneleri olmasını garanti edersiniz. – Reti43

+0

Doğru, saklanan her dizenin "b" ... "olduğunu" ve "değerlendirmenin b" olarak yorumlanması gerektiğini farketmedim ... ":) Yorum için teşekkürler! – darkless

1

yerine, eval kullanmayın lütfen:

import codecs 
s = 'žluťoučký' 
x = str(s.encode('utf-8')) 

# strip quotes 
x = x[2:-1] 

# unescape 
x = codecs.escape_decode(x)[0].decode('utf-8') 

# profit 
x == s 
+0

Değerlendirilmeyen sürüm için teşekkürler, çift eğik çizgileri tek eğik çizgi haline getirmek için 'escape_decode' eksik.Yine de, yönteme dokümanlar bulamıyorum: https://docs.python.org/3.5/library/codecs.html – darkless