Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Por que um quantificador não ganancioso às vezes não funciona no Oracle regex?

É um ERRO!


Você está certo que em Perl, 'A=1,B=2,C=3,' =~ /.*B=.*?,/; print $& imprime A=1,B=2,

O que você encontrou é um bug que ainda existe no Oracle Database 11g R2. Se exatamente o mesmo átomo de expressão regular (incluindo o quantificador, mas excluindo o modificador de ganância) aparecer duas vezes em uma expressão regular, ambas as ocorrências terão a ganância indicada pela primeira aparição, independentemente da ganância especificada pela segunda. Que este é um bug é claramente demonstrado por estes resultados (aqui, "o mesmo átomo de expressão regular exato" é [^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,

A única diferença entre as duas expressões regulares é que a "boa" exclui 'x' como uma possível correspondência na segunda lista de correspondências. Como 'x' não aparece na string de destino, excluí-lo não deve fazer diferença, mas como você pode ver, remover o 'x' faz uma grande diferença. Isso deve ser um bug.

Aqui estão mais alguns exemplos do Oracle 11.2:(SQL Fiddle com ainda mais exemplos )
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,

O padrão é consistente:a ganância da primeira ocorrência é usada para a segunda ocorrência, seja ela ou não.