Pregunta

Estoy intentando implementar la eliminación de escape de cadenas con expresiones regulares de Python y referencias inversas, y no parece querer funcionar muy bien.Estoy seguro de que es algo que estoy haciendo mal pero no puedo entender qué...

>>> 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 reemplazar \\[char] con \[char], pero las referencias inversas en Python no parecen seguir las mismas reglas que en todas las demás implementaciones que he usado.¿Alguien podría arrojar algo de luz?

¿Fue útil?

Solución

¿No es eso lo que hace el segundo ejemplo de Anders?

En 2.5 también hay un string-escape codificación que puedes 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 
>>> 

Otros consejos

Bueno, creo que quizás te hayas perdido la r o hayas 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 entendí es lo solicitado.

Sospecho que la solicitud más común es esta:

>>> 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 debería leer el libro de Ken Thompson. Reflexiones sobre la confianza", donde nuestro héroe usa un ejemplo similar para explicar los peligros de confiar en compiladores que usted mismo no ha arrancado desde el código de máquina.

La idea es leer una cadena con escape y quitarle el escape (una característica que falta notablemente en Python, para la cual no deberías necesitar recurrir a expresiones regulares en primer lugar).Desafortunadamente, las barras invertidas no me engañan...

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 imprimiera es

This is 
ridiculous

La representación de Python de la cadena de resultados lo está engañando.La expresión de Python:

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

representa la cadena

This is \n a test \r

que es lo que creo que querías.Intente agregar 'imprimir' delante de cada una de sus llamadas a 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

Marca;Este segundo ejemplo requiere que cada carácter de escape se coloque inicialmente en una matriz, lo que genera un KeyError si la secuencia de escape no está en la matriz.Morirá con cualquier cosa que no sean los tres caracteres proporcionados (pruébelo \v), y enumerar todas las secuencias de escape posibles cada vez que desee eliminar el escape de una cadena (o mantener una matriz global) es una solución realmente mala.Análogo a PHP, eso está usando preg_replace_callback() con una lambda en lugar de preg_replace(), lo cual es completamente innecesario en esta situación.

Lo siento si parezco un idiota al respecto, simplemente estoy completamente frustrado con Python.Esto es compatible con todos los demás motores de expresiones regulares que he usado y no puedo entender por qué no funciona.

Gracias por responder;el string.decode('string-escape') La función es precisamente lo que estaba buscando inicialmente.Si alguien tiene una solución general al problema de la referencia inversa de expresiones regulares, no dude en publicarla y la aceptaré también como respuesta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top