Oracle
 sql >> Base de données >  >> RDS >> Oracle

Pourquoi un quantificateur non gourmand ne fonctionne-t-il pas parfois dans Oracle regex ?

C'est un BUG !

Vous avez raison qu'en Perl, 'A=1,B=2,C=3,' =~ /.*B=.*?,/; print $& affiche A=1,B=2,

Vous êtes tombé sur un bogue qui existe toujours dans Oracle Database 11g R2. Si le même atome d'expression régulière (incluant le quantificateur mais excluant le modificateur de gourmandise) apparaît deux fois dans une expression régulière, les deux occurrences auront la gourmandise indiquée par la première apparition, quelle que soit la gourmandise spécifiée par la seconde. Qu'il s'agisse d'un bogue est clairement démontré par ces résultats (ici, "exactement le même atome d'expression régulière" est [^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,

La seule différence entre les deux expressions régulières est que la "bonne" exclut 'x' comme correspondance possible dans la deuxième liste de correspondance. Étant donné que 'x' n'apparaît pas dans la chaîne cible, l'exclure ne devrait faire aucune différence, mais comme vous pouvez le voir, supprimer le 'x' fait une grande différence. Ce doit être un bug.

Voici quelques exemples supplémentaires d'Oracle 11.2 :(SQL Fiddle avec encore plus d'exemples )

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,

Le modèle est cohérent :la gourmandise de la première occurrence est utilisée pour la deuxième occurrence, qu'elle le soit ou non.