regex (texte .*) (texte .*)? problématique

Le
ctobini
Bonjour,

Je voudrais parser du code SQL qui se présente sous 2 formes
possibles :

1. SELECT blablabla FROM blablabla

ou

2. SELECT blablabla FROM blablabla WHERE blablabla

J'essaie d'appliquer une regex :

if (/ (SELECT .*) (FROM .*) (WHERE .*)? /x) {
my $select = $1 ;
my $from = $2 ;
my $where = $3
}

Mon problème est que même en présence de WHERE, ma variable $2 capte
WHERE.

Pourriez-vous m'aider à comprendre ceci ?

En vous remerciant,

C. Tobini
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
espie
Le #18336791
In article ctobini

Bonjour,

Je voudrais parser du code SQL qui se présente sous 2 formes
possibles :

1. SELECT blablabla FROM blablabla

ou

2. SELECT blablabla FROM blablabla WHERE blablabla

J'essaie d'appliquer une regex :

if (/ (SELECT .*) (FROM .*) (WHERE .*)? /x) {
my $select = $1 ;
my $from = $2 ;
my $where = $3
}

Mon problème est que même en présence de WHERE, ma variable $2 capte
WHERE.



Oui, c'est normal. Les expressions regulieres sont gloutonnes.

A part ca, avant de te conseiller plus avant, j'aimerais savoir ce que tu
essaies de faire. Vu le potentiel en trous de securite de SQL, je m'en
voudrais de te donner juste les outils pour te pendre...
ctobini
Le #18337101
Bonjour et merci de la réponse,

Je n'utilise pas ce code SQL, mon but est d'extraire les noms de
tables, colonnes et conditions (WHERE) afin de faire une liste sous
forme de tableur. Je viens de commencer un nouveau boulot avec du code
non documenté, je dois reconstituer un puzzle basé sur du reporting
BO.

Je comprends que le .* soit délicat à manipuler et glouton, néanmoins
quand le WHERE est effectivement dans le code, je ne comprends pas
pourquoi le regex (WHERE .*)? semble problématique car si j'enlève
le ? ça fonctionne.

C. Tobini

Oui, c'est normal. Les expressions regulieres sont gloutonnes.

A part ca, avant de te conseiller plus avant, j'aimerais savoir ce que tu
essaies de faire. Vu le potentiel en trous de securite de SQL, je m'en
voudrais de te donner juste les outils pour te pendre...


mpg
Le #18337581
Le (on) jeudi 08 janvier 2009 20:04, ctobini a écrit (wrote) :

Je comprends que le .* soit délicat à manipuler et glouton, néanmoins
quand le WHERE est effectivement dans le code, je ne comprends pas
pourquoi le regex (WHERE .*)? semble problématique car si j'enlève
le ? ça fonctionne.



Imagine que tu es le parseur associé à la regex

/ (SELECT .*) (FROM .*) (WHERE .*)?/

et qu'on te donne à manger la chaîne

" SELECT foo FROM table WHERE condition "

Tu commences par voir " SELECT " au début de la chaîne, c'est très bien
parce que c'est ce que tu cherchais. Ensuite tu avales tout ce que tu peux
aussi loin que possible (c'est le .*), donc jusqu'à la fin de la chaîne,
puis tu vois qu'après il doit y avoir " FROM ". Manque de bol, il y a pas
ça après la fin de la chaîne, vu que par définition il y a rien après la
fin. Bon, tu essaies en avalant que jusqu'a un caractère avant la fin, puis
deux, etc, jusqu'à ce que tu sois t'arrête assez tôt pour voir le " FROM ".

Ensuite tu recommences à essayer de tout manger jusqu'à la fin (.*) puis tu
vois que ça va pas parce qu'il y a pas d'espace après. Donc tu manges tout
jusqu'à la fin moins 1, et là tu vois que le prochain caractère est un
espace : très bien, ça matche. À ce moment-là, la règle (partie (WHERE .*)?
de la regex) est qu'il *peut* y avoir un WHERE suivit de trucs, mas ce
n'est pas obligé. Donc tu n'as aucune raison de revenir en arrière et tu
t'arrêtes.

En vrai, ça ne se passe pas comme ça, notamment parce que le moteur de regex
de Perl fait beaucoup d'optimisations (par exemple sur le premier .* il
saura que ça vaut pas la peine d'essayer jusqu'à la fin parce qu'il faut au
moins la place de mettre un " FROM " derrière), mis fonctionnellement c'est
équivalent.

C'est ça qu'on entend quand on dit que les regex sont gloutonnes (greedy en
anglais) : un .* va d'abord essayer de tout prendre jusqu'à la fin, et ne
va en revenir en arrière que s'il est obligé de le faire.

On peut rendre n'importe quel quantificateur non-glouton en Perl en le
faisant suivre de « ? ».

Manuel.
YBM
Le #18338901
mpg a écrit :
[snip le bel exposé]



Sur ce sujet, une excellente référence est :

http://perl.plover.com/yak/regex/

entre autres propos de l'excellent MJD :

http://perl.plover.com/
Publicité
Poster une réponse
Anonyme