バグです!
Perlでは、'A=1,B=2,C=3,' =~ /.*B=.*?,/; print $&
を印刷します A=1,B=2,
を出力します
あなたが遭遇したのは、Oracle Database11gR2にまだ存在するバグです。まったく同じ正規表現アトム(数量詞を含み、貪欲修飾子を除く)が正規表現に2回出現する場合、2番目の出現で指定された貪欲に関係なく、両方の出現で最初の出現で示される貪欲があります。これがバグであることは、これらの結果によって明確に示されています(ここでは、「まったく同じ正規表現アトム」は[^B]*
です。 ):
SQL> SELECT regexp_substr('A=1,B=2,C=3,', '[^B]*B=[^Bx]*?,') as good FROM dual;
GOOD
--------
A=1,B=2,
SQL> SELECT regexp_substr('A=1,B=2,C=3,', '[^B]*B=[^B]*?,') as bad FROM dual;
BAD
-----------
A=1,B=2,C=3,
2つの正規表現の唯一の違いは、「適切な」正規表現では、2番目の一致リストで一致する可能性があるものとして「x」が除外されることです。 'x'はターゲット文字列に表示されないため、除外しても違いはありませんが、ご覧のとおり、'x'を削除すると大きな違いが生じます。それはバグである必要があります。
Oracle 11.2のその他の例を次に示します。(SQLFiddleとさらに多くの例> )
SELECT regexp_substr('A=1,B=2,C=3,', '.*B=.*?,') FROM dual; => A=1,B=2,C=3,
SELECT regexp_substr('A=1,B=2,C=3,', '.*B=.*,') FROM dual; => A=1,B=2,C=3,
SELECT regexp_substr('A=1,B=2,C=3,', '.*?B=.*?,') FROM dual; => A=1,B=2,
SELECT regexp_substr('A=1,B=2,C=3,', '.*?B=.*,') FROM dual; => A=1,B=2,
-- Changing second operator from * to +
SELECT regexp_substr('A=1,B=2,C=3,', '.*B=.+?,') FROM dual; => A=1,B=2,
SELECT regexp_substr('A=1,B=2,C=3,', '.*B=.+,') FROM dual; => A=1,B=2,C=3,
SELECT regexp_substr('A=1,B=2,C=3,', '.+B=.+,') FROM dual; => A=1,B=2,C=3,
SELECT regexp_substr('A=1,B=2,C=3,', '.+?B=.+,') FROM dual; => A=1,B=2,
パターンは一貫しています。最初の発生の貪欲さは、2番目の発生に使用されるべきかどうかに関係なく使用されます。