Pythonにおける正規表現の貪欲さの制限
正規表現はデフォルトで 貪欲です。これは、可能な限り多くの文字を 捕捉することを意味します。 例を使って見てみましょう。次のような文字列があるとします:
txt = 'aeeex zzz x kkk'
この文字列で、次のパターンに従って部分文字列
'aeeex'を見つけたいとします:
文字 'a'、その後に任意の文字
が1回以上、その後文字 'x':
res = re.sub('a.+x', '!', txt)
print(res)
'! zzz
x kkk'という文字列を得る必要があるのに、'! kkk'という文字列が出力されます。
問題は、私たちの正規表現が文字'a'から文字
'x'までのすべての文字を探していることです。
しかし、私たちの文字列には'x'という文字が2つあります!
貪欲さのせいで、正規表現は最後のxまで探しに行ってしまい、
その結果、私たちが必要としていたものではないものを
捕捉してしまうのです。
もちろん、多くの場合、この動作は私たちが 必要としているものです。しかし、この具体的なケースでは 貪欲さをキャンセルし、正規表現に最初のxまでを 探すように伝える必要があります。この場合、 繰り返し演算子の後に疑問符を置きます:
res = re.sub('a.+?x', '!', txt)
print(res) # '! zzz x kkk'という文字列を出力する
貪欲さはすべての繰り返し演算子に対して制限できます:
*、?、
{} – このように: *?、??
そして{}?。
次の文字列が与えられます:
txt = 'aba accca azzza wwwwa'
両端に文字'a'があるすべての文字列を見つけ、
それぞれを'!'に置き換える正規表現を
書きなさい。文字'a'の間には
('a'以外の)任意の文字が存在できます。