Escapezeichen für reguläre Ausdrücke in Python

229

Ich möchte die Eingabe eines Benutzers als Regex-Muster für die Suche nach Text verwenden. Es funktioniert, aber wie kann ich mit Fällen umgehen, in denen der Benutzer Zeichen mit Bedeutung in Regex einfügt? Beispielsweise möchte der Benutzer nach Word suchen (s): Die Regex-Engine nimmt die (s)als Gruppe. Ich möchte, dass es wie eine Schnur behandelt wird "(s)". Ich kann replaceauf Benutzereingabe laufen und das (mit \(und das )mit ersetzen, \)aber das Problem ist, dass ich für jedes mögliche Regex-Symbol ersetzen muss. Kennst du einen besseren Weg?

MichaelT
quelle

Antworten:

324

Verwenden Sie dazu die re.escape()Funktion:

4.2.3 reModulinhalt

Escape (String)

Rückgabezeichenfolge mit allen nicht alphanumerischen Schrägstrichen; Dies ist nützlich, wenn Sie mit einer beliebigen Literalzeichenfolge übereinstimmen möchten, die möglicherweise Metazeichen mit regulären Ausdrücken enthält.

Suchen Sie in einem vereinfachenden Beispiel nach dem Vorkommen der angegebenen Zeichenfolge, gefolgt von 's', und geben Sie das Übereinstimmungsobjekt zurück.

def simplistic_plural(word, text):
    word_or_plural = re.escape(word) + 's?'
    return re.match(word_or_plural, text)
ddaa
quelle
53

Sie können re.escape () verwenden :

re.escape (string) Gibt einen String mit allen nicht alphanumerischen Backslashes zurück. Dies ist nützlich, wenn Sie mit einer beliebigen Literalzeichenfolge übereinstimmen möchten, die möglicherweise Metazeichen mit regulären Ausdrücken enthält.

>>> import re
>>> re.escape('^a.*$')
'\\^a\\.\\*\\$'
gimel
quelle
3

Ist leider re.escape()nicht für die Ersatzzeichenfolge geeignet:

>>> re.sub('a', re.escape('_'), 'aa')
'\\_\\_'

Eine Lösung besteht darin, den Ersatz in ein Lambda zu legen:

>>> re.sub('a', lambda _: '_', 'aa')
'__'

weil der Rückgabewert des Lambda von re.sub()als Literalzeichenfolge behandelt wird .

Owen
quelle
3
Das replArgument für re.subist eine Zeichenfolge, kein regulärer Ausdruck. sich darauf zu bewerben re.escapemacht überhaupt keinen Sinn.
Tripleee
5
@tripleee Das ist falsch, das replArgument ist keine einfache Zeichenfolge, es wird analysiert. Zum Beispiel re.sub(r'(.)', r'\1', 'X')wird Xnicht zurückkehren \1.
Flimm
4
Hier ist die relevante Frage, um dem replArgument zu entkommen : stackoverflow.com/q/49943270/247696
Flimm
3
In Version 3.3 geändert: Das Zeichen '_' wird nicht mehr maskiert. In Version 3.7 geändert: Nur Zeichen, die in einem regulären Ausdruck eine besondere Bedeutung haben können, werden maskiert. (Warum hat es so lange
Cees Timmerman