2012-05-07 6 views
6

¿Alguien podría explicarme este comportamiento extraño? Espero que ambos reemplacen los métodos para que funcionen o para que no funcionen al mismo tiempo. ¿Soy solo yo o hay alguien que no encuentre esto coherente?Comportamiento extraño de re.sub con cadenas utf-8

>>> u'è'.replace("\xe0","") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 0: ordinal not in range(128) 
>>> re.sub(u'è','\xe0','',flags=re.UNICODE) 
'' 

(Tenga en cuenta que no estoy pidiendo una explicación de por qué u'è'.replace ("\ xe0", "") genera un error!)

+0

'unicode.replace' no es el mismo método que' re.sub'. – Daenyth

+0

Por supuesto. Y mi punto es que deberían comportarse coherentemente para las mismas entradas. – luke14free

+1

Son preguntas como esta las que llevaron a la aplicación más estricta de cadenas Unicode vs. Byte en Python 3. –

Respuesta

2

De Unicode Doc

los argumentos para estos métodos pueden ser cadenas Unicode o cadenas de 0 bits de 8 bits. Las cadenas de 8 bits se convertirán a Unicode antes de llevar a la operación; Se utilizará la codificación ASCII por defecto de Python, por lo caracteres superiores a 127 causará una excepción

De Re Doc:

Este módulo proporciona expresión regular las operaciones de juego similar a las que se encuentran en Perl. Tanto los patrones como las cadenas que se buscarán pueden ser cadenas Unicode, así como cadenas de 8 bits.

Dado que para el módulo Re no especifica explícitamente el indicador Unicode, no está intentando la conversión y, por lo tanto, no provoca el error. Es por eso que no se comportan de forma coherente

+0

Mhh. No muy convencido sobre lo de la bandera; >>> re.sub (u'è ',' \ xe0 ',' ', flags = re.UNICODE) todavía me devuelve' ' – luke14free

+0

Es perfectamente posible que el módulo re atrape esa excepción y no sea transparente al respecto, solo una corazonada, no confirmada. – subiet

+1

No funcionó para mí :(Python es absolutamente horrible con el soporte de Unicode. He perdido 3 días y aún no he podido terminar una función muy simple de lectura y cambio de escritura. – oriadam

0

Python 2.X tiene un manejo poco natural de la codificación, que requiere una conversión implícita. Tratará de jugar con cadenas Unicode y No Unicode, cuando el usuario no se encargue de la conversión. Al final, eso no resuelve el problema: la codificación debe ser reconocida por el desarrollador desde el primer momento. Python 2 simplemente hace las cosas menos explícitas y un poco menos obvias.

>>> u'è'.replace(u"\xe0", u"") 
u'\xe8' 

Ese es su ejemplo original, excepto que específicamente le dije a Python que todas las cadenas eran unicode. Si no lo hace, Python intentará convertirlos. Y debido a que la codificación predeterminada en Python 2 es ASCII, obviamente eso fallará con su ejemplo.

La codificación es un tema complicado, pero con algunos buenos hábitos (como la conversión temprana, estar siempre seguro de qué tipo de datos maneja el programa en un punto determinado), generalmente (e insisto, EN GENERAL) va bien .

Espero que ayude!