問題
例えば、"star*"
という文字列を含む文字列を正規表現で検索したいとき。
pattern = 'star*'
print(re.match(pattern, 'starbucks') != None) # True
print(re.match(pattern, 'star') != None) # True
print(re.match(pattern, 'star*bucks') != None) # True
一番下の'star*bucks'
だけTrueになってほしいところですが、すべてTrueになってしまいました。
これは*
が正規表現のメタ文字として認識されてしまっていることに起因します。
*, \, [], ()
等でも同じ問題が起き得ます。
つまり、以下のようにすれば、意図通りにマッチできます。
pattern = 'star\*' # *を\でエスケープ
print(re.match(pattern, 'starbucks') != None) # False
print(re.match(pattern, 'star') != None) # False
print(re.match(pattern, 'star*bucks') != None) # True
では、patternが変数であるときにはどうすればよいでしょうか。
結論
re.escape
を使えば、文字列に適切なエスケープを実施してくれます。
(ここでの「適切」は、「正規表現の邪魔をしない」ことを指しています)
6.2. re — 正規表現操作 — Python 3.6.5 ドキュメント
pattern = 'star*'
pattern = re.escape(pattern) # pattern = 'star\*'となる
print(re.match(pattern, 'starbucks') != None) # True
print(re.match(pattern, 'star') != None) # True
print(re.match(pattern, 'star*bucks') != None) # True
おまけ
あたりまえではあるのですが、どうしてもre
モジュールを使う必要があるのでなければ、str.replace()
を使うという選択肢もあります。