2010-05-06 9 views
11

La siguiente cadena Unicode y puede existir por sí mismos si se ha definido de forma explícita:¿Cómo convierto un Unicode en una cadena en el nivel de Python?

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

Si sólo he u'Andr\xc3\xa9' asignado a una variable como la de arriba, ¿Cómo se convierte a 'Andr\xc3\xa9' en Python 2.5 o 2.6?

EDIT:

me hizo lo siguiente:

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

que fija mi problema. ¿Puede alguien explicarme qué está pasando exactamente?

+0

Esta es la TERCERA pregunta que ha hecho en menos de un día, basada en el mismo malentendido. 'u'Andr \ xc3 \ xa9'' es una tontería obtenida por una doble codificación con utf8 y latin1. ¡Simplemente no hagas eso! –

+0

Eso es lo que me desconcierta. ¿Cómo pasó de acento original a lo que es ahora? Cuando dices doble codificación con utf8 y latin1, ¿hay un total de 3 codificaciones (2 utf8 + 1 latin1)? ¿Cuál es el orden de la codificación desde el estado original hasta el actual? –

Respuesta

11

Usted parece haber conseguido sus codificaciones confusos hacia arriba. Parece probable que lo que realmente quiere es u'Andr\xe9' que es equivalente a 'André'.

Pero lo que parece ser una codificación UTF-8 que se ha decodificado incorrectamente. Puede solucionarlo convirtiendo la cadena Unicode en una cadena ordinaria. No estoy seguro de lo que es la mejor manera, pero esto parece que funciona:

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

Entonces decodificarlo correctamente:

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

Ahora bien, es en el formato correcto.

Sin embargo, en lugar de hacer esto, si es posible, debe intentar averiguar por qué los datos han sido codificados incorrectamente en primer lugar, y solucionar ese problema allí.

-1

Parece que

str(value_uni) 

debería funcionar ... al menos, lo hizo cuando lo probé.

EDIT: Resulta que esto solo funciona porque la codificación predeterminada de mi sistema es, hasta donde puedo decir, ISO-8859-1 (Latin-1). Así que para una versión independiente de la plataforma de esto, trate de

value_uni.encode('latin1') 
+0

Lo intenté pero recibí UnicodeEncodeError: el códec 'ascii' no puede codificar caracteres en la posición 4-5: ordinal no está dentro del rango (128).¿Qué versión de Python estás usando y en qué sistema operativo? –

+0

Python 2.6.4 en Linux ... aunque ahora que lo pienso, es posible que la codificación predeterminada de mi sistema sea diferente a la tuya. Aunque no estoy seguro de cuál es mi codificación predeterminada. –

+0

OK, lo tengo, pruebe el nuevo método. –

3

value_uni.encode('utf8') o cualquier codificación que necesita.

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

+1

Solo para agregar. Lo anterior puede parecer lo mismo, pero el literal Unicode está hecho de puntos de código que corresponden a símbolos y la cadena normal no tiene sentido a menos que conozca la codificación. – dhill

+0

obtengo 'Andr \ xc3 \ x83 \ xc2 \ xa9', ¿esto no es diferente de 'Andr \ xc3 \ xa9'? –

+0

@ Thierry: Eso es lo que obtienes si te equivocas y pones UTF-8 en unicode. –

0

explicación simplificada. El tipo str solo puede contener caracteres del rango 0-255. Si desea almacenar unicode (que puede contener caracteres de un rango mucho más amplio) en str, primero debe codificar unicode para dar formato adecuado para str, por ejemplo UTF-8.

Para hacer esto, codifique en su objeto str y como argumento proporcione la codificación deseada, por ejemplo this_is_str = value_uni.encode('utf-8').

Puede leer un artículo más extenso y detallado (sobre el manejo de Unicode) aquí: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!).

Otro excelente artículo (este tiempo específico de Python): Unicode HOWTO

1

El OP no está convirtiendo a ascii ni utf-8. Es por eso que los métodos sugeridos encode no funcionarán. Prueba esto:

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

El negocio chr(ord(x)) obtiene el valor numérico del carácter Unicode (que mejor ajuste en un byte para su aplicación), y la llamada ''.join es un modismo que convierte una lista de enteros de nuevo a un ordinario cuerda. Sin duda hay una manera más elegante.

1

Si tiene u'Andr\xc3\xa9', probablemente fue originalmente UTF-8 de cualquier fuente de la que se haya obtenido. De ser posible, vuelva a leer la fuente decodificando con 'utf-8'. De lo contrario sólo revertir el error:.

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

Usted preguntó (en un comentario) "" "Eso es lo que me desconcierta ¿Cómo ha ido de ella original, acentuada a lo que es ahora Cuando dices doble codificación con UTF-8? y latin1, ¿eso es un total de 3 codificaciones (2 utf8 + 1 latin1)? ¿Cuál es el orden de la codificación del estado original al actual? "" "

En la respuesta de Mark Byers, él dice" "" lo que parece ser una codificación UTF-8 que se ha decodificado incorrectamente "" ". Usted ha aceptado su respuesta. ¿Pero todavía estás desconcertado? Bien, aquí está la descripción paso a paso:

Nota: Todas las cadenas se mostrarán usando (implícitamente) repr(). unicodedata.name() se usará para verificar los contenidos. De esta forma, las variaciones en la codificación de la consola no pueden confundir la interpretación de las cadenas.

Estado inicial: tiene un objeto Unicode que ha llamado u1. Contiene e-aguda:

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

codificar u1 como UTF-8 y el nombre el resultado s:

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

a descifrar s utilizando latin1 - incorrecta; s fue codificado usando utf8, NO latin1. El resultado es basura sin sentido.

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

Por favor, comprenda: unicode_object.encode('x').decode('y) cuando x = y es normalmente [ver nota siguiente] un disparate; levantará una excepción si tienes suerte; si no tiene suerte, creará en silencio un galimatías. También comprenda que crear silenciosamente un galimatías no es un error; no hay una forma general en que Python (o cualquier otro idioma) pueda detectar que se haya cometido un sinsentido. Esto se aplica particularmente cuando se trata de latin1, porque los 256 puntos de código mapean 1 a 1 con los primeros 256 puntos de código Unicode, por lo que es imposible obtener un UnicodeDecodeError de str_object.decode ('latin1').

Por supuesto, anormalmente (uno espera que sea anormal) es posible que tenga que revertir tales tonterías haciendo gibberish_unicode_object.encode('y').decode('x') como se sugiere en varias respuestas a su pregunta.

Cuestiones relacionadas