53966


次のようなスクリプトがあった場合、私が思っていた結果は" **aab** "なのですが、" **aaaab** "が返ってきてしまいます。

[code]

    s = "aaaab"
    pattern = r"a{2,4}?b"
    
    match = re.search(pattern, s)
    if match is not None:
        print(match.group(0))
    
[/code]

patternを **r"a{2,4}?"** にすると" **aa** "が返ってくるのに **r"a{2,4}?b"**
だとaの数が4つになるのが気持ち悪いです。  
これはPythonのバグなのでしょうか。公式ドキュメントには"少なく 繰り返したものとマッチする"と書かれているのですが。。

バージョンは 2.7.11 です。  
(バージョン3ではどのような挙動になるのかも、教えていただけると助かります。)


CC BY-SA 4.0
2019-04-05T14:18:36.193
53964
2019-04-05T15:21:08.703
24908
question
python 正規表現
Pythonの正規表現の"{m,n}?"の挙動について


`search()`の仕様からこのような挙動になります。

<https://docs.python.org/ja/3/library/re.html#re.search>

> string を走査し、正規表現 pattern がマッチを生じさせる最初の場所を探して

文字列の左端から順々にマッチするかどうか試して、マッチした時点で終了します。マッチ開始位置が0に近いものが優先されるわけです。

もし希望の動作が欲しいなら、`search()`は使えません。すべての位置からのマッチを記録して、マッチした長さが最小のものを選びます。


CC BY-SA 4.0
2019-04-05T14:49:58.367
53965
2019-04-05T14:49:58.367
3475
53964
answer


バグではありません。

Python 2、Python 3、および Perl の正規表現は、デフォルトでは **最左** ・最長マッチをするようになっています。`?`
をつけることで最長マッチが最短マッチに変わりますが、最左マッチであることは変わりません。また、最左マッチが最短マッチより優先します。このため今回の差が生まれます。

より具体的に言うと、`a{2,4}?b`という正規表現は、最初の `a` がマッチした **後** に `a` の回数を最小にしようとします。したがって 1
文字目の `a` にマッチした後「`b` のマッチに失敗し、`a` のマッチに成功する」を 3 回繰り返し、最後に `b`
にマッチするという挙動になります。

したがって、これはバグではありません。`re` パッケージは正しく最も少ない回数マッチしていますが、その開始地点は最左になるという訳です。

（ところで、そもそも今回の正規表現では最初から `aab` や `a{2}b`
という正規表現でマッチすれば良さそうです。おそらく質問者さんには固有の背景があってこのような書き方になったのかと思いますが。）


CC BY-SA 4.0
2019-04-05T14:50:22.783
53966
2019-04-05T15:21:08.703
2019-04-05T15:21:08.703
19110
19110
53964
answer