Pythonでの正規表現文字列のエスケープ


229

一部のテキストを検索するための正規表現パターンとして、ユーザーからの入力を使用したいと思います。それは機能しますが、ユーザーが正規表現で意味のある文字を入力するケースをどのように処理できますか?たとえば、ユーザーがWordを検索したい場合、(s)正規表現エンジンはを(s)グループとして使用します。文字列のように扱いたい"(s)"。私は実行することができreplace、ユーザ入力に置き換えると(して\()\)ますが、問題は、私はすべての可能な正規表現のシンボルに置き換える行う必要がありますです。もっと良い方法を知っていますか?

回答:


324

re.escape()このための関数を使用します。

4.2.3 reモジュールの内容

エスケープ(文字列)

英数字以外のすべてのバックスラッシュを含む文字列を返します。これは、正規表現のメタ文字が含まれている可能性がある任意のリテラル文字列に一致させる場合に便利です。

単純な例として、提供された文字列の出現を検索し、オプションで「s」を続けて、一致オブジェクトを返します。

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

53

re.escape()を使用できます:

re.escape(string)すべての非英数字がバックスラッシュされた文字列を返します。これは、正規表現のメタ文字が含まれている可能性がある任意のリテラル文字列に一致させる場合に便利です。

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

3

残念ながら、re.escape()置換文字列には適していません:

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

解決策は、置換をラムダに入れることです:

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

ラムダの戻り値はre.sub()リテラル文字列として扱われるためです。


3
へのrepl引数re.subは文字列であり、正規表現ではありません。それに適用re.escapeしても、そもそも意味がありません。
tripleee

5
@tripleee不正解です。repl引数は単純な文字列ではなく、解析されます。たとえば、ではなくre.sub(r'(.)', r'\1', 'X')が返されます。X\1
Flimm

4
ここでエスケープに関連する質問ですrepl:引数をstackoverflow.com/q/49943270/247696
Flimm

3
バージョン3.3で変更:「_」文字はエスケープされなくなりました。バージョン3.7で変更:正規表現で特別な意味を持つことができる文字のみがエスケープされます。(なぜこんなに時間がかかったのですか?)
Cees Timmerman '11

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.