Question

J'essaie d'implémenter la déséchappement de chaîne avec les expressions régulières et les références arrière Python, et cela ne semble pas vouloir très bien fonctionner.Je suis sûr que c'est quelque chose que je fais mal mais je n'arrive pas à comprendre quoi...

>>> 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'

J'aimerais remplacer \\[char] par \[char], mais les références arrière en Python ne semblent pas suivre les mêmes règles que dans toutes les autres implémentations que j'ai jamais utilisées.Quelqu'un pourrait-il nous éclairer ?

Était-ce utile?

La solution

N'est-ce pas ce que fait le deuxième exemple d'Anders ?

En 2.5, il y a aussi un string-escape encodage que vous pouvez appliquer :

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

Autres conseils

Eh bien, je pense que vous avez peut-être manqué le r ou mal compté les barres obliques inverses...

"\\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
>>>

Si j'ai bien compris, c'est ce qui était demandé.

Je soupçonne que la demande la plus courante est la suivante :

>>> 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 \
>>>

L'étudiant intéressé devrait également lire l'ouvrage de Ken Thompson Réflexions sur la confiance", dans lequel notre héros utilise un exemple similaire pour expliquer les dangers de faire confiance à des compilateurs que vous n'avez pas démarrés vous-même à partir du code machine.

L'idée est que je vais lire une chaîne échappée et la supprimer (une fonctionnalité qui manque notamment à Python, pour laquelle vous ne devriez pas avoir besoin de recourir à des expressions régulières en premier lieu).Malheureusement, je ne me laisse pas tromper par les barres obliques inverses...

Autre exemple illustratif :

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

Ce que j'aimerais qu'il imprime, c'est

This is 
ridiculous

Vous êtes trompé par la représentation Python de la chaîne de résultat.L'expression Python :

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

représente la chaîne

This is \n a test \r

c'est, je pense, ce que tu voulais.Essayez d'ajouter « print » devant chacun de vos appels p.sub() pour imprimer la chaîne réelle renvoyée au lieu d'une représentation Python de la chaîne.

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

Marque;son deuxième exemple nécessite que chaque caractère d'échappement soit initialement lancé dans un tableau, ce qui génère une KeyError si la séquence d'échappement ne se trouve pas dans le tableau.Il mourra avec tout sauf les trois caractères fournis (essayez \v), et énumérer toutes les séquences d'échappement possibles à chaque fois que vous souhaitez supprimer l'échappement d'une chaîne (ou conserver un tableau global) est une très mauvaise solution.Analogue à PHP, cela utilise preg_replace_callback() avec un lambda au lieu de preg_replace(), ce qui est totalement inutile dans cette situation.

Je suis désolé si je passe pour un con, je suis juste complètement frustré par Python.Ceci est pris en charge par tous les autres moteurs d'expressions régulières que j'ai jamais utilisés, et je ne comprends pas pourquoi cela ne fonctionnerait pas.

Merci d'avoir répondu;le string.decode('string-escape') la fonction est précisément ce que je recherchais au départ.Si quelqu'un a une solution générale au problème de référence arrière des regex, n'hésitez pas à la publier et je l'accepterai également comme réponse.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top