Je to CHYBA!
Máte pravdu, že v Perlu 'A=1,B=2,C=3,' =~ /.*B=.*?,/; print $&
vytiskne A=1,B=2,
Narazili jste na chybu, která stále existuje v Oracle Database 11g R2. Pokud se přesně stejný atom regulárního výrazu (včetně kvantifikátoru, ale bez modifikátoru nenasytnosti) objeví v regulárním výrazu dvakrát, oba výskyty budou mít nenasytnost indikovanou prvním výskytem bez ohledu na nenasytnost specifikovanou druhým. Že se jedná o chybu, jasně ukazují tyto výsledky (zde je "přesně stejný atom regulárního výrazu" [^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,
Jediný rozdíl mezi těmito dvěma regulárními výrazy je v tom, že „dobrý“ výraz vylučuje „x“ jako možnou shodu v druhém shodném seznamu. Protože 'x' se v cílovém řetězci neobjevuje, jeho vyloučení by nemělo mít žádný rozdíl, ale jak vidíte, odstranění 'x' znamená velký rozdíl. To musí být chyba.
Zde je několik dalších příkladů z Oracle 11.2:(SQL Fiddle s ještě dalšími příklady )
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,
Vzor je konzistentní:nenasytnost prvního výskytu se použije pro druhý výskyt, ať už by to tak mělo být nebo ne.