[ruby-dev:49736] [Ruby trunk Bug#12584][Rejected] Regexp using repetition with alternation doesn't match greedily

From: shyouhei@...
Date: 2016-07-14 05:28:50 UTC
List: ruby-dev #49736
Issue #12584 has been updated by Shyouhei Urabe.

Status changed from Open to Rejected

それはそういうものです。知りうる限りでは perl php python node でもそのように動きますので。これの動きを変えるのは弊害のほうが大きいです。

```
% perl -e '"---ed---" =~ /(?:[^d]|ed)*/; warn $&'
---e at -e line 1.
```

```
% php -a
Interactive shell

php > preg_match('/(?:[^d]|ed)*/', "---ed---", $m); echo $m[0];
---e
php >
```

```
% python
Python 2.7.11 (default, Jan 22 2016, 08:29:18)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> re.search("((?:[^d]|ed)*)", "---ed---").group(0)
'---e'
>>>
```

```
% node --interactive
> "---ed---".match(/(?:[^d]|ed)*/)
[ '---e', index: 0, input: '---ed---' ]
>
```

----------------------------------------
Bug #12584: Regexp using repetition with alternation doesn't match greedily
https://bugs.ruby-lang.org/issues/12584#change-59617

* Author: 亮太 鈴木
* Status: Rejected
* Priority: Normal
* Assignee: 
* ruby -v: ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]
* Backport: 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN
----------------------------------------
正規表現で選択子 `|` の外側で最大量指定子 `*` による繰り返しを行った場合、最大でない部分文字列にマッチしてしまうことがあるようです。
以下に再現例を示します。

ある文字列から、「区切り文字`d` 以外の文字`/[^d]/`」と「エスケープされた区切り文字`/ed/`」からなる部分文字列を抽出することを考えます。
次の例では、文字列全体にマッチするべきであるにもかかわらず、前半部分にしかマッチしていません。

~~~ ruby
"---ed---".match(/(?:[^d]|ed)*/)
# => #<MatchData "---e"> 
~~~

次の例のように、カッコ内の`|` の前後を入れ替えると、期待した通りに動きます。

~~~ ruby
"---ed---".match(/(?:ed|[^d])*/)
# => #<MatchData "---ed---"> 
~~~

この挙動がMac の以下の3つのバージョンで再現することを確認しました。

* ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]
* ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin14]
* ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-darwin15.5.0]

以上、よろしくお願いします。



-- 
https://bugs.ruby-lang.org/

In This Thread

Prev Next