findall()
、finditer()
のパターン文字列で選択演算子'|'
を用いるとき、選択文字列の順序によって結果が変わってくる点に注意が必要。
たとえばreモジュール関数の場合、以下の例のようになる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import re s = "a,aa,aaa,aaaa,aaaaa" print(re.findall(r'aa|aaa', s)) # ['aa', 'aa', 'aa', 'aa', 'aa', 'aa'] print(re.findall(r'aaa|aa', s)) # ['aa', 'aaa', 'aaa', 'aaa', 'aa'] [print(x.group(0), end=' ') for x in re.finditer('aa|aaa', s)]; print() # aa aa aa aa aa aa [print(x.group(0), end=' ') for x in re.finditer('aaa|aa', s)]; print() # aa aaa aaa aaa aa |
'aa|aaa'
とした場合以下の順番でマッチしていく。
"a,|aa|,|aa|a,aaaa,aaaaa"
"a,|aa|,|aa|a,|aa|aa,aaaaa"
"a,|aa|,|aa|a,|aa|aa|,aaaaa"
"a,|aa|,|aa|a,|aa|aa|,|aa|aaa"
"a,|aa|,|aa|a,|aa|aa|,|aa|aa|a"
'aaa|aa'
とした場合は以下の順番でマッチしていく
"a,|aa|,aaa,aaaa,aaaaa"
"a,|aa|,|aaa|,aaaa,aaaaa"
"a,|aa|,|aaa|,|aaa|a,aaaaa"
"a,|aa|,|aaa|,|aaa|a,aaaaa"
"a,|aa|,|aaa|,|aaa|a,|aaa|aa"
"a,|aa|,|aaa|,|aaa|a,|aaa|aa|"
つまり、各マッチングの段階で選択演算子'|'
の左側からマッチする部分をまず探し、該当しなければ演算子の右へと判定パターンを変えていく。
このため、演算子の左のパターンが右のパターンより短いと、先にそちらがマッチングされるので右の長いパターンがマッチしなくなることがある。
この動作は、正規表現オブジェクトのメソッドについても同じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import re s = "a,aa,aaa,aaaa,aaaaa" matchobj1 = re.compile(r'aa|aaa') matchobj2 = re.compile(r'aaa|aa') print(matchobj1.findall(s)) # ['aa', 'aa', 'aa', 'aa', 'aa', 'aa'] print(matchobj2.findall(s)) # ['aa', 'aaa', 'aaa', 'aaa', 'aa'] [print(x.group(0), end=' ') for x in matchobj1.finditer(s)]; print() # aa aa aa aa aa aa [print(x.group(0), end=' ') for x in matchobj2.finditer(s)]; print() # aa aaa aaa aaa aa |