2008-08-17 10 views
11

Estoy tratando de implementar el descarte de cadenas con Python regex y backreferences, y no parece querer funcionar muy bien. Estoy seguro de que es algo que estoy haciendo mal, pero no puedo averiguar qué ...Python Expresiones regulares para implementar unescaping de cadena

>>> import re 
>>> mystring = r"This is \n a test \r" 
>>> p = re.compile("\\\\(\\S)") 
>>> p.sub("\\1", mystring) 
'This is n a test r' 
>>> p.sub("\\\\\\1", mystring) 
'This is \\n a test \\r' 
>>> p.sub("\\\\1", mystring) 
'This is \\1 a test \\1' 

me gustaría sustituir \\ [Char] con \ [Char], sino referencias hacia atrás en Python no parece seguir las mismas reglas que en cualquier otra implementación que haya usado alguna vez. ¿Alguien podría arrojar algo de luz?

Respuesta

8

No es eso lo Anders 'segundo ejemplo lo hace?

En 2.5 también hay un string-escape codificación se puede aplicar:

>>> mystring = r"This is \n a test \r" 
>>> mystring.decode('string-escape') 
'This is \n a test \r' 
>>> print mystring.decode('string-escape') 
This is 
a test 
>>> 
3

Bueno, creo que podría haber perdido la R o contado mal las barras invertidas ...

"\\n" == r"\n" 

>>> import re 
>>> mystring = r"This is \\n a test \\r" 
>>> p = re.compile(r"[\\][\\](.)") 
>>> print p.sub(r"\\\1", mystring) 
This is \n a test \r 
>>> 

Lo cual, si he entendido es lo que se solicitó.

Sospecho que la petición más común es la siguiente:

>>> d = {'n':'\n', 'r':'\r', 'f':'\f'} 
>>> p = re.compile(r"[\\]([nrfv])") 
>>> print p.sub(lambda mo: d[mo.group(1)], mystring) 
This is \ 
a test \ 
>>> 

El estudiante interesado también debe leer de Reflections on Trusting Trust" Ken Thompson, en el que nuestro héroe utiliza un ejemplo similar para explicar los peligros de los compiladores de confianza no ha bootstrap de código de máquina usted mismo.

0

Está siendo engañado por la representación de Python de la cadena de resultados. La expresión de Python:

'This is \\n a test \\r' 

representa la cadena

This is \n a test \r 

que es creo lo que quería. Intente agregar 'print' delante de cada una de sus llamadas p.sub() para imprimir la cadena real devuelta en lugar de una representación de Python de la cadena.

>>> mystring = r"This is \n a test \r" 
>>> mystring 
'This is \\n a test \\r' 
>>> print mystring 
This is \n a test \r 
0

La idea es que voy a leer en una cadena escapada, y que unescape (que carecen de una característica particular de Python, que no debería ser necesario recurrir a las expresiones regulares en el primer lugar). Por desgracia, no estoy siendo engañado por las barras invertidas ...

Otro ejemplo ilustrativo:

>>> mystring = r"This is \n ridiculous" 
>>> print mystring 
This is \n ridiculous 
>>> p = re.compile(r"\\(\S)") 
>>> print p.sub('bloody', mystring) 
This is bloody ridiculous 
>>> print p.sub(r'\1', mystring) 
This is n ridiculous 
>>> print p.sub(r'\\1', mystring) 
This is \1 ridiculous 
>>> print p.sub(r'\\\1', mystring) 
This is \n ridiculous 

Lo que me gustaría que se imprime es

This is 
ridiculous 
0

Marcos; su segundo ejemplo requiere que todos los caracteres escapados se arrojen inicialmente a una matriz, lo que genera un KeyError si la secuencia de escape no está en la matriz. Morirá en cualquier cosa que no sean los tres caracteres proporcionados (pruebe), y enumerar todas las posibles secuencias de escape cada vez que quiera desentrañar una cadena (o mantener una matriz global) es una solución realmente mala. De forma análoga a PHP, eso es usar preg_replace_callback() con una lambda en lugar de preg_replace(), lo cual es completamente innecesario en esta situación.

Lo siento si me estoy volviendo loco, estoy completamente frustrado con Python.Esto es compatible con cualquier otro motor de expresión regular que haya usado alguna vez, y no puedo entender por qué esto no funcionaría.

Gracias por responder; la función string.decode('string-escape') es precisamente lo que estaba buscando inicialmente. Si alguien tiene una solución general al problema de retro-expresión regex, no dude en publicarlo y lo aceptaré como una respuesta también.

Cuestiones relacionadas