2008-08-17 10 views
11

Ich versuche, String Unescaping mit Python Regex und Rückwärtsreferenzen zu implementieren, und es scheint nicht sehr gut funktionieren wollen. Ich bin sicher, es ist etwas, was ich falsch mache, aber ich kann nicht herausfinden, was ...Python Reguläre Ausdrücke zu implementieren String Unescaping

>>> 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 mag würde zu \\ [char] mit \ [char] ersetzen, aber Rückreferenzierungen in Python scheinen nicht den gleichen Regeln zu folgen, die sie bei jeder anderen Implementierung, die ich jemals benutzt habe, befolgen. Könnte jemand etwas Licht abwerfen?

Antwort

8

Ist das nicht das, was Anders 'zweites Beispiel?

In 2.5 gibt es auch eine string-escape kodiert, 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 
>>> 
3

Nun, ich glaube, Sie könnten die Schrägstriche die r oder falsch gezählt verpasst haben ...

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

Was, wenn ich verstanden, was angefordert wurde.

Ich vermute, dass die häufigere Anforderung ist dies:

>>> 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 Schüler auch Ken Thompson lesen sollte Reflections on Trusting Trust", wobei unser Held verwendet ein ähnliches Beispiel die Gefahren des vertrauensvollen Compiler erklären Sie nicht Bootstrap haben Maschinencode selbst.

0

Sie werden von Pythons Darstellung der Ergebniszeichenfolge betrogen. Der Python-Ausdruck:

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

stellt die Zeichenfolge

This is \n a test \r 

welches ich denke, was Sie wollten. Versuchen Sie, 'print' vor jedem Ihrer p() -Aufrufe einzufügen, um die tatsächlich zurückgegebene Zeichenfolge anstelle einer Python-Darstellung der Zeichenfolge zu drucken.

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

Die Idee ist, dass ich in einem maskierten String gelesen werden, und unescape es (eine Funktion vor allem aus Python fehlt, die Sie sollten nicht in erster Linie in reguläre Ausdrücke zurückgreifen müssen). Leider durch die Schrägstriche Ich bin nicht ...

ausgetrickst

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 

Was ich möchte ist drucken

This is 
ridiculous 
0

Mark; sein zweites Beispiel erfordert, dass jedes maskierte Zeichen anfänglich in ein Array geworfen wird, das einen KeyError generiert, wenn sich die Escape-Sequenz nicht im Array befindet. Es wird auf alles außer den drei Zeichen sterben (geben Sie einen Versuch), und das Aufzählen jeder möglichen Escape-Sequenz jedes Mal, wenn Sie eine Zeichenkette enternieren wollen (oder ein globales Array behalten), ist eine wirklich schlechte Lösung. Analog zu PHP, das verwendet preg_replace_callback() mit einem Lambda anstelle von preg_replace(), was in dieser Situation völlig unnötig ist.

Es tut mir leid, wenn ich als ein Schwanz davon abkommen werde, ich bin nur völlig frustriert mit Python.Dies wird von jeder anderen Engine für reguläre Ausdrücke unterstützt, die ich je benutzt habe, und ich kann nicht verstehen, warum das nicht funktionieren würde.

Vielen Dank für Ihre Antwort. 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ückreferenzproblem hat, können Sie es gerne posten und ich werde das auch als Antwort akzeptieren.