2010-05-06 9 views
11

Il seguente unicode e la stringa possono esistere da soli se definito in modo esplicito:Come posso convertire un unicode in una stringa a livello di Python?

>>> value_str='Andr\xc3\xa9' 
>>> value_uni=u'Andr\xc3\xa9' 

Se ho solo u'Andr\xc3\xa9' assegnato ad una variabile come sopra, come faccio a convertirlo in 'Andr\xc3\xa9' in Python 2.5 o 2.6?

EDIT:

ho fatto la seguente:

>>> value_uni.encode('latin-1') 
'Andr\xc3\xa9' 

che risolve il mio problema. Qualcuno può spiegarmi cosa sta succedendo esattamente?

+0

Questa è la terza domanda che hai chiesto in meno di un giorno, il tutto basato sullo stesso equivoco. 'u'Andr \ xc3 \ xa9'' è un'assurdità ottenuta da una doppia codifica con utf8 e latin1. Basta non farlo! –

+0

Questo è ciò che mi sta sconcertando. Come è andato dal suo accento originale a quello che è adesso? Quando dici doppia codifica con utf8 e latin1, è un totale di 3 codifiche (2 utf8 + 1 latin1)? Qual è l'ordine della codifica dallo stato originale a quello attuale? –

risposta

11

ti sembra di avere ottenuto le vostre codifiche confuse su. Sembra probabile che quello che vuoi veramente sia u'Andr\xe9' che è equivalente a 'André'.

Ma quello che sembra essere una codifica UTF-8 che è stata decodificata in modo errato. Puoi correggerlo convertendo la stringa unicode in una stringa ordinaria. Non sono sicuro di quello che è il modo migliore, ma questo sembra funzionare:

>>> ''.join(chr(ord(c)) for c in u'Andr\xc3\xa9') 
'Andr\xc3\xa9' 

Poi decodificare correttamente:

>>> ''.join(chr(ord(c)) for c in u'Andr\xc3\xa9').decode('utf8') 
u'Andr\xe9'  

Ora è nel formato corretto.

Tuttavia, anziché eseguire questa operazione, se possibile, provare a capire perché i dati sono stati codificati in modo errato in primo luogo e risolvere il problema.

-1

Sembra

str(value_uni) 

dovrebbe funzionare ... almeno, lo ha fatto quando l'ho provato.

EDIT: Si scopre che questo funziona solo perché la codifica predefinita del mio sistema è, per quanto ne so, ISO-8859-1 (Latin-1). Così, per una versione indipendente dalla piattaforma di questo, provare a

value_uni.encode('latin1') 
+0

Ho provato, ma ottengo UnicodeEncodeError: codec 'ascii' non può codificare i caratteri in posizione 4-5: ordinale non nel range (128).Quale versione di Python stai usando e su quale sistema operativo? –

+0

Python 2.6.4 su Linux ... anche se ora ci penso, è possibile che la codifica predefinita del mio sistema sia impostata in modo diverso dalla tua. Tuttavia, non sono completamente sicuro di quale sia la mia codifica predefinita. –

+0

OK, capito, prova il nuovo metodo. –

3

value_uni.encode('utf8') o qualsiasi altra cosa la codifica è necessario.

Vedi http://docs.python.org/library/stdtypes.html#str.encode

+1

Solo per aggiungere. Quanto sopra può sembrare lo stesso, ma il letterale Unicode è fatto di punti di codice che corrispondono a simboli e la stringa normale non ha senso se non si conosce la codifica. – dhill

+0

Ottengo 'Andr \ xc3 \ x83 \ xc2 \ xa9', non è diverso da 'Andr \ xc3 \ xa9'? –

+0

@Thierry: Questo è ciò che ottieni se rovini e inserisci UTF-8 in unicode. –

0

spiegazione semplificata. Il tipo str è in grado di contenere solo caratteri compresi nell'intervallo 0-255. Se si desidera memorizzare unicode (che può contenere caratteri da un intervallo molto più ampio) in str, è necessario prima codificare unicode in formato adatto per str, ad esempio UTF-8.

Per eseguire questa operazione, il metodo call codifica sul proprio oggetto str e come argomento fornisce la codifica desiderata, ad esempio this_is_str = value_uni.encode('utf-8').

È possibile leggere un articolo più lungo e più approfondito (e indipendente dalla lingua) sulla gestione Unicode qui: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!).

Un altro eccellente articolo (questa volta specifico per Python): Unicode HOWTO

1

L'OP non sta convertendo in ascii né utf-8. Ecco perché i metodi suggeriti encode non funzioneranno. Prova questo:

v = u'Andr\xc3\xa9' 
s = ''.join(map(lambda x: chr(ord(x)),v)) 

Il chr(ord(x)) azienda ottiene il valore numerico del carattere unicode (che misura migliore in un byte per la vostra applicazione), e la chiamata ''.join è un idioma che converte un elenco di interi tornare a un normale stringa. Senza dubbio c'è un modo più elegante.

1

Se si dispone di u'Andr\xc3\xa9', probabilmente era originariamente UTF-8 da qualsiasi fonte fosse stato ottenuto. Se possibile, leggi nuovamente la decodifica del sorgente con "utf-8". In caso contrario, basta invertire l'errore:.

>>> print u'Andr\xc3\xa9'.encode('latin-1').decode('utf-8') 
André 
5

hai chiesto (in un commento) "" "Questo è ciò che mi ha sconcertante Come è andata da esso originale accentata a quello che è ora Quando si dice doppia codifica con utf8? e latin1, è un totale di 3 codifiche (2 utf8 + 1 latin1)? Qual è l'ordine della codifica dallo stato originale a quello attuale? "" "

Nella risposta di Mark Byers, dice" "" quello che sembra essere una codifica UTF-8 che è stata decodificata in modo errato "" ". Hai accettato la sua risposta. Ma sei ancora perplesso? OK, ecco la descrizione dettagliata:

Nota: Tutte le stringhe verranno visualizzate utilizzando (implicitamente) repr(). unicodedata.name() verrà utilizzato per verificare i contenuti. In questo modo, le variazioni nella codifica della console non possono confondere l'interpretazione delle stringhe.

Stato iniziale: si dispone di un oggetto Unicode che è stato denominato u1. Contiene e-acuta:

>>> u1 = u'\xe9' 
>>> import unicodedata as ucd 
>>> ucd.name(u1) 
'LATIN SMALL LETTER E WITH ACUTE' 

si codifica U1 come UTF-8 e il nome il risultato s:

>>> s = u1.encode('utf8') 
>>> s 
'\xc3\xa9' 

a decodificare s utilizzando latin1 - CORRETTAMENTE; s è stato codificato usando utf8, NON latin1. Il risultato è spazzatura senza senso.

>>> u2 = s.decode('latin1') 
>>> u2 
u'\xc3\xa9' 
>>> ucd.name(u2[0]); ucd.name(u2[1]) 
'LATIN CAPITAL LETTER A WITH TILDE' 
'COPYRIGHT SIGN' 
>>> 

Vi prego di capire: unicode_object.encode('x').decode('y) quando x = y è normalmente [vedi nota sotto] una sciocchezza; solleverà un'eccezione se sarai fortunato; se sei sfortunato creerà silenziosamente parole senza senso. Inoltre, ti preghiamo di comprendere che la creazione silenziosa del linguaggio non è un bug: non esiste un modo generale in cui Python (o qualsiasi altra lingua) possa rilevare che è stata commessa un'assurdità. Ciò si applica in particolare quando è coinvolto latin1, perché tutti i 256 codepoint eseguono il mapping 1 su 1 con i primi 256 codecoint Unicode, quindi è impossibile ottenere un UnicodeDecodeError da str_object.decode ('latin1').

Ovviamente, (si spera che sia anormale) potrebbe essere necessario annullare una tale assurdità facendo gibberish_unicode_object.encode('y').decode('x') come suggerito in varie risposte alla tua domanda.

Problemi correlati