Frage

Ich versuche, String-Unescaping mit Python-Regex und Rückreferenzen zu implementieren, und es scheint nicht sehr gut zu funktionieren.Ich bin mir sicher, dass es etwas ist, was ich falsch mache, aber ich kann nicht herausfinden, was ...

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

Ich würde gerne \\[char] durch \[char] ersetzen, aber Rückverweise in Python scheinen nicht denselben Regeln zu folgen wie in jeder anderen Implementierung, die ich jemals verwendet habe.Könnte jemand etwas Licht ins Dunkel bringen?

War es hilfreich?

Lösung

Ist das nicht genau das, was Anders‘ zweites Beispiel bewirkt?

In 2.5 gibt es auch eine string-escape Kodierung, die Sie anwenden können:

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

Andere Tipps

Nun, ich denke, Sie haben vielleicht das r übersehen oder die Backslashes falsch gezählt ...

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

Wenn ich das verstanden habe, wurde genau das verlangt.

Ich vermute, dass die häufigere Anfrage folgende ist:

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

Der interessierte Student sollte auch Ken Thompsons lesen Überlegungen zum Thema „Vertrauen vertrauen“, wobei unser Held ein ähnliches Beispiel verwendet, um die Gefahren zu erklären, die entstehen, wenn man Compilern vertraut, die man nicht selbst aus dem Maschinencode gebootstrappt hat.

Die Idee ist, dass ich eine mit Escapezeichen versehene Zeichenfolge einlese und die Escapezeichenfolge aufhebe (eine Funktion, die in Python besonders fehlt und für die Sie überhaupt nicht auf reguläre Ausdrücke zurückgreifen müssen).Leider lasse ich mich von den Backslashes nicht täuschen ...

Ein weiteres anschauliches Beispiel:

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

Ich möchte, dass es gedruckt wird

This is 
ridiculous

Sie werden durch Pythons Darstellung der Ergebniszeichenfolge ausgetrickst.Der Python-Ausdruck:

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

stellt die Zeichenfolge dar

This is \n a test \r

Das ist meiner Meinung nach genau das, was Sie wollten.Versuchen Sie, vor jedem Ihrer p.sub()-Aufrufe „print“ einzufügen, um die tatsächlich zurückgegebene Zeichenfolge anstelle einer Python-Darstellung der Zeichenfolge auszugeben.

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

Markieren;In seinem zweiten Beispiel muss jedes Escape-Zeichen zunächst in ein Array geworfen werden, wodurch ein KeyError generiert wird, wenn die Escape-Sequenz zufällig nicht im Array enthalten ist.Es wird bei allem außer den drei bereitgestellten Zeichen sterben (versuchen Sie es mit \v), und jedes Mal, wenn Sie die Escape-Sequenz einer Zeichenfolge aufheben möchten (oder ein globales Array beizubehalten), alle möglichen Escape-Sequenzen aufzulisten, ist eine wirklich schlechte Lösung.Analog zu PHP, das ist using preg_replace_callback() mit einem Lambda statt preg_replace(), was in dieser Situation völlig unnötig ist.

Es tut mir leid, wenn ich deswegen wie ein Idiot rüberkomme, ich bin einfach total frustriert von Python.Dies wird von jeder anderen Engine für reguläre Ausdrücke unterstützt, die ich je verwendet habe, und ich kann nicht verstehen, warum das nicht funktionieren sollte.

Danke für das Antworten;Die string.decode('string-escape') Funktion ist genau das, was ich ursprünglich gesucht habe.Wenn jemand eine allgemeine Lösung für das Regex-Rückverweisproblem hat, kann er diese gerne posten, und ich akzeptiere diese auch als Antwort.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top