To BŁĄD!
Masz rację, że w Perlu 'A=1,B=2,C=3,' =~ /.*B=.*?,/; print $&
drukuje A=1,B=2,
Natknąłeś się na błąd, który nadal istnieje w Oracle Database 11g R2. Jeśli dokładnie ten sam atom wyrażenia regularnego (w tym kwantyfikator, ale z wyłączeniem modyfikatora zachłanności) pojawia się dwukrotnie w wyrażeniu regularnym, oba wystąpienia będą miały zachłanność wskazaną przez pierwsze pojawienie się, niezależnie od zachłanności określonej przez drugie. Te wyniki wyraźnie pokazują, że jest to błąd (tutaj "dokładnie ten sam atom wyrażenia regularnego" to [^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,
Jedyna różnica między tymi dwoma wyrażeniami regularnymi polega na tym, że „dobre” wyklucza „x” jako możliwe dopasowanie z drugiej listy dopasowań. Ponieważ „x” nie pojawia się w łańcuchu docelowym, wykluczenie go nie powinno mieć znaczenia, ale jak widać, usunięcie „x” robi dużą różnicę. To musi być błąd.
Oto kilka przykładów z Oracle 11.2:(SQL Fiddle z jeszcze większą liczbą przykładów )
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,
Wzorzec jest spójny:chciwość z pierwszego wystąpienia jest używana w drugim wystąpieniu, niezależnie od tego, czy ma być, czy nie.