Discussion:
Difficile avec les expressions regulaires !
(trop ancien pour répondre)
Utilisateur1
2009-10-22 06:21:19 UTC
Permalink
a.. J'ai de gros problemes pour faire fonctionner ces deux expressions
régulaires.

Je veux identifier deux types de requêtes sql simples différentes que je
peux recevoir, pour effectuer un traitement différent avant d'envoyer la
requête au sgbd.
Dans les deux cas à tester, j'ai toujours "INCONNU" comme résultat.

J'ai bien utilisé i à la fin pour ne pas avoir de problèmes pour les
majuscules et minuscules, et j'ai essayé avec et sans, meme probleme.
[\ ]{0,} sert pour ne pas rater une requete si elle contient un espace en
plus entre deux parties de la requete.

Ou est l'erreur ?

Merci de votre assistance !

voici le code

// Premiere chaine à savoir intercepter
//$SQLRequete ="SELECT CURRVAL('seq_montruc_id')";

// Deuxieme chaine a savoir intercepter
a.. $Chaine ="SELECT mavaleur FROM matable WHERE lechamp = 1234";
a..
a..


IF(preg_match('/^(SELECT){1}[\ ]{0,}(CURRVAL\(\'){1}([a-zA-Z]+)(\'\)){1}$/i'
, $Chaine)==1)
a.. {
a.. echo('CURRVAL');
a.. }
a.. elseif(preg_match('/^(SELECT){1} [\ ]{0,} ([a-z]){0,} (\.){0,1}
(FROM){0,1} [\ ]{0,} ([a-z]){0,} (WHERE){0,1}
[\ ]{0,}([a-z]){0,}[\ ]{0,}[=]{1}[\ ]{0,}([0-9]){0,}$/i', $Chaine)==1)
a.. {
a.. echo('SELECT FROM ');
a.. }
a.. else
a.. {
a.. echo('INCONNU');
a.. }
Bruno Desthuilliers
2009-10-22 09:14:32 UTC
Permalink
Post by Utilisateur1
a.. J'ai de gros problemes pour faire fonctionner ces deux expressions
régulaires.
Pour les écrire, déjà...
Post by Utilisateur1
Je veux identifier deux types de requêtes sql simples différentes que je
peux recevoir, pour effectuer un traitement différent avant d'envoyer la
requête au sgbd.
Dans les deux cas à tester, j'ai toujours "INCONNU" comme résultat.
J'ai bien utilisé i à la fin pour ne pas avoir de problèmes pour les
majuscules et minuscules, et j'ai essayé avec et sans, meme probleme.
[\ ]{0,} sert pour ne pas rater une requete si elle contient un espace en
plus entre deux parties de la requete.
Ou est l'erreur ?
Mauvaise lecture de la doc et complexification inutile.
Post by Utilisateur1
voici le code
// Premiere chaine à savoir intercepter
"SELECT CURRVAL('seq_montruc_id')";
'/^(SELECT){1}[\ ]{0,}(CURRVAL\(\'){1}([a-zA-Z]+)(\'\)){1}$/i'
tu te fatigues bien la vie, là... Déjà, vire tout le bordel inutile. Et
pense que si la requête est générée par code, elle peut avoir des
espaces (sauts de lignes inclus) un peu partout.

"/^ *SELECT +CURRVAL *\( *'([a-zA-Z_]+)' *\) *$/i"
Post by Utilisateur1
// Deuxieme chaine a savoir intercepter
"SELECT mavaleur FROM matable WHERE lechamp = 1234";
'/^(SELECT){1} [\ ]{0,} ([a-z]){0,} (\.){0,1}
(FROM){0,1} [\ ]{0,} ([a-z]){0,} (WHERE){0,1}
[\ ]{0,}([a-z]){0,}[\ ]{0,}[=]{1}[\ ]{0,}([0-9]){0,}$/i'
Urg....

"/^ *SELECT +([a-zA-Z_]+) +FROM +([a-zA-Z_]+) +WHERE ([a-zA-Z_]+) *=
*([0-9]+) *$/i"


NB : Pas testé, mais ça devrait te remettre sur le bon chemin. Petits
rappels au passage:

- un littéral matche ce même littéral. Donc, "[=]" est une façon
inutilement compliquée d'écrire "=" (idem pour les espaces...)
- le quantifieur par défaut est "{1,1}". Donc, "^(SELECT){1} " est une
façon inutilement compliquée d'écrire "^SELECT "
- "{0,}" s'écrit plus simplement "*"
- "{1,}" s'écrit plus simplement "+"
- "{0,1}" s'écrit plus simplenent "?"

D'une manière générale, n'utilise les quantifieurs complexes ("{,}") que
si tu en a vraiment besoin. Idem pour les groupements (parenthèses) et
les classes ("[...]").

Accessoirement, en utilisant des doubles quotes pour définir ton
expression, tu n'a pas besoin d'échapper les simples quotes, ce qui
améliore quelque peu la lisibilité.

Autre point: tu ne précises pas le contexte d'utilisation, mais sauf si
tu a la main sur le code qui _génère_ les requêtes, parser du SQL à
coups de regexps est assez casse-gueule. Particulièrement sur des
requêtes SELECT. Je peux te donner quelques examples simples de SELECT
que ta regexp ne capturera pas:

SELECT * FROM ma_table WHERE mon_champ = 123;
SELECT champ1, champ2 FROM ma_table WHERE mon_champ = 123;
SELECT champ1 as tutu FROM ma_table WHERE mon_champ = 123;
SELECT ma_table.champ1 FROM ma_table WHERE ma_table.mon_champ = 123;

et je n'ai fait qu'effleurer la surface de l'iceberg - je pourrais t'en
tartiner des pages et des pages.
Olivier Miakinen
2009-10-22 09:37:21 UTC
Permalink
Post by Bruno Desthuilliers
Post by Utilisateur1
a.. J'ai de gros problemes pour faire fonctionner ces deux expressions
régulaires.
Pour les écrire, déjà...
Moi j'aime bien le mot « régulaires » qui devrait mettre d'accord
(contre lui ?) aussi bien les tenants de « régulières » que ceux de
« rationnelles ». ;-)
Post by Bruno Desthuilliers
[...]
tu te fatigues bien la vie, là... Déjà, vire tout le bordel inutile. Et
pense que si la requête est générée par code, elle peut avoir des
espaces (sauts de lignes inclus) un peu partout.
"/^ *SELECT +CURRVAL *\( *'([a-zA-Z_]+)' *\) *$/i"
Note qu'ici tu ne traites que les espaces, pas les tabulations ou les
sauts de ligne... Mais comme tu le dis plus loin il y a plein d'autres
cas qui ne sont pas forcément traités non plus.
Post by Bruno Desthuilliers
[...]
Post by Utilisateur1
'/^(SELECT){1} [\ ]{0,} ([a-z]){0,} (\.){0,1}
(FROM){0,1} [\ ]{0,} ([a-z]){0,} (WHERE){0,1}
[\ ]{0,}([a-z]){0,}[\ ]{0,}[=]{1}[\ ]{0,}([0-9]){0,}$/i'
Urg....
:-D
Post by Bruno Desthuilliers
"/^ *SELECT +([a-zA-Z_]+) +FROM +([a-zA-Z_]+) +WHERE ([a-zA-Z_]+) *=
*([0-9]+) *$/i"
Pour aller jusqu'au bout de la logique des espaces multiples, il manque
un '+' après 'WHERE '.
Post by Bruno Desthuilliers
NB : Pas testé, mais ça devrait te remettre sur le bon chemin. Petits
[...]
Oui, c'était une bonne idée de les faire. Je rappelle pour ma part que
le groupe fr.comp.lang.regexp accueillera avec bienveillance toute
question sur les expressions régulaires (décidément, ce terme me plaît).
Post by Bruno Desthuilliers
Autre point: tu ne précises pas le contexte d'utilisation, mais sauf si
tu as la main sur le code qui _génère_ les requêtes, parser du SQL à
coups de regexps est assez casse-gueule. [...] je pourrais t'en
tartiner des pages et des pages.
[OUI]


Cordialement,
--
Olivier Miakinen
Bruno Desthuilliers
2009-10-22 16:37:58 UTC
Permalink
(snip)
Post by Olivier Miakinen
Post by Bruno Desthuilliers
"/^ *SELECT +CURRVAL *\( *'([a-zA-Z_]+)' *\) *$/i"
Note qu'ici tu ne traites que les espaces, pas les tabulations ou les
sauts de ligne...
yeps - je voulais y revenir mais j'ai oublié :(
Post by Olivier Miakinen
Post by Bruno Desthuilliers
"/^ *SELECT +([a-zA-Z_]+) +FROM +([a-zA-Z_]+) +WHERE ([a-zA-Z_]+) *=
*([0-9]+) *$/i"
Pour aller jusqu'au bout de la logique des espaces multiples, il manque
un '+' après 'WHERE '.
Bien vu - merci pour les corrections !-)

Mickael Wolff
2009-10-22 10:07:53 UTC
Permalink
Post by Utilisateur1
Je veux identifier deux types de requêtes sql simples différentes que je
peux recevoir, pour effectuer un traitement différent avant d'envoyer la
requête au sgbd.
Dans les deux cas à tester, j'ai toujours "INCONNU" comme résultat.
Je ne reviendrais pas sur les regex, Bruno a largement pointé tes
maladresses. Par contre, il serait intéressant d'expliquer ton besoin.
L'usage des regex n'est certainement pas une bonne idée ici.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Continuer la lecture sur narkive:
Loading...