Expression reguliere sur une requete Insert

Expression reguliere sur une requete Insert - PHP - Programmation

Marsh Posté le 27-09-2005 à 14:11:16    

Salut,
 
j'aimerai pouvoir récuperer toutes les valeurs entrée dans une requete Insert. Par exemple :

Code :
  1. insert into maTable values ('73','castor','pollux','');


 
J'aimerai pouvoir récuperer avec la fonction preg_match :  
$matches[1] = 73
$matches[2] = castor
...
 
J'ai essayé mais vu que je n'y connais pas grand chose en expression réguliere je fais n'importe quoi...

Code :
  1. if(preg_match("/^insert into .+ values.(['(.*)'],)+(['(.*)']).+/i",$req,$cleprim)) {...}


 
Donc ici j'essaye de capturer la répetition 'xxx', puis le dernier 'xxx' sans la virgule mais ca ne marche pas :D
 
J'ai fais ca aussi mais c'est pas mieux :D

Code :
  1. if(preg_match("/^insert into .+ values.(['(.*)',]).+/i",$req,$cleprim)) {...}


 
J'ai regardé plein de docs mais bon quand on y connait rien ca reste obscure ces expression regulieres :D
J'espere que vous arriverez a m'aider, merci bcp :)
 
 

Reply

Marsh Posté le 27-09-2005 à 14:11:16   

Reply

Marsh Posté le 27-09-2005 à 14:19:14    

le nombre de champs est constant ?

Reply

Marsh Posté le 27-09-2005 à 14:19:52    

Nan on ne le connait pas a l'avance, ca doit pouvoir s'appliquer a n'importe quelle requete d'insertion...

Reply

Marsh Posté le 27-09-2005 à 14:27:11    

avec preg_match_all
et #'(.*)'#U
    * [0]=>'73'
    * [1]=>'castor'
    * [2]=>'pollux'

Reply

Marsh Posté le 27-09-2005 à 14:30:35    

afbilou a écrit :

avec preg_match_all
et #'(.*)'#U
    * [0]=>'73'
    * [1]=>'castor'
    * [2]=>'pollux'


si il y a un \' dans un des champs ça ne fonctionne plus
dans ce genre de cas je pense que c'est plus simple de faire sans regexp

Reply

Marsh Posté le 27-09-2005 à 14:30:39    

Merci de ton aide !!
Donc j'ai testé :
if(preg_match_all("#'(.*)'#U",$req,$cleprim)) {...}
 
Le test marche et j'entre dans mon if par contre :
[0] donne "array"
[1] donne "array"
[2] donne rien
 
Donc ca n'a pas l'air de marcher... A moins que j'ai fais une connerie :D

Reply

Marsh Posté le 27-09-2005 à 14:31:41    

soju a écrit :

si il y a un \' dans un des champs ça ne fonctionne plus
dans ce genre de cas je pense que c'est plus simple de faire sans regexp


 
Ca peut arriver qu'il y ai des \ je pense, c'est sur meme :/
Comment faire sans expression reguliere sinon ? Ca va etre + compliqué et surtout moins propre non ?

Reply

Marsh Posté le 27-09-2005 à 14:39:33    

Loizo a écrit :

Merci de ton aide !!
Donc j'ai testé :
if(preg_match_all("#'(.*)'#U",$req,$cleprim)) {...}
 
Le test marche et j'entre dans mon if par contre :
[0] donne "array"
[1] donne "array"
[2] donne rien
 
Donc ca n'a pas l'air de marcher... A moins que j'ai fais une connerie :D


ben wé c toi qui fait mal :/
 
c'est [0][0] [0][1] [0][2] ...
en meme temps c'etait facile de le deviner ... sachant qu'il te retourne un array a chake fois !

Reply

Marsh Posté le 27-09-2005 à 14:42:38    

C'est vrai j'avais meme pas calculé, mais alors je comprend pas trop pk il retourne un array. En tout cas merci, je teste ca de suite :)
 
 
Edit : Nickel ca fonctionne !! Merci bcp :)  
En faisant $matches[1][1] ca m'affiche castor sans les '' en plus, ca le fait !!


Message édité par Loizo le 27-09-2005 à 14:44:40
Reply

Marsh Posté le 27-09-2005 à 14:44:27    

Je ferais ça :
 

Code :
  1. $req = "insert into maTable values ('73','castor','pollux','');";
  2. preg_match('#values \\((.+?)\\);#i', $req, $matches);
  3. print_r(explode(',', $matches[1]))


 
edité pour qu'HFR zappe pas les \........

Message cité 1 fois
Message édité par sielfried le 27-09-2005 à 14:45:55

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 27-09-2005 à 14:44:27   

Reply

Marsh Posté le 27-09-2005 à 14:44:35    

le tableau [0] c'est les captures donc tu auras les ' dedans puisk'ils sont explicitement dans le masque de capture.
 
le tableau [1] c'est les parentheses capturantes dans les captures ... tu n'auras pas les ' donc !
c'est le tableau 1 qu'il te faut en general !
 
[1][0] [1][1] [1][.....] etc ...

Reply

Marsh Posté le 27-09-2005 à 14:46:52    

sielfried a écrit :

Je ferais ça :
 

Code :
  1. $req = "insert into maTable values ('73','castor','pollux','');";
  2. preg_match('#values \\((.+?)\\);#i', $req, $matches);
  3. print_r(explode(',', $matches[1]))


 
edité pour qu'HFR zappe pas les \........


[mode_chieur]
et si il y a des , dans les champs ?
[/mode_chieur]

Reply

Marsh Posté le 27-09-2005 à 14:50:40    

Loizo a écrit :

Ca peut arriver qu'il y ai des \ je pense, c'est sur meme :/
Comment faire sans expression reguliere sinon ? Ca va etre + compliqué et surtout moins propre non ?


bon si tu veux absolument une regexp, tu vas avoir besoin d'assertions : http://fr2.php.net/manual/fr/refer [...] assertions
 
exemple : #(?<!\\\)'(.*)(?<!\\\)'#

Reply

Marsh Posté le 27-09-2005 à 14:50:44    

soju a écrit :

[mode_chieur]
et si il y a des , dans les champs ?
[/mode_chieur]


 
Ouais c'est vrai, mais pareil avec un \' et ton preg_match_all si je ne m'abuse.
 
Le problème c'est qu'il peut y avoir n'importe quoi. :spamafote:

Message cité 1 fois
Message édité par sielfried le 27-09-2005 à 14:51:14

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 27-09-2005 à 14:54:02    

sielfried a écrit :

Ouais c'est vrai, mais pareil avec un \' et ton preg_match_all si je ne m'abuse.

le preg_match_all était de afbilou
 
sinon la soluce avec assertions fonctionne

Code :
  1. $req = "insert into maTable values ('73','castor','po\\\\'llux','');";
  2. if (preg_match_all('#(?<!\\\\\\\)\'(.*)(?<!\\\\\\\)\'#U', $req, $match))
  3. {
  4. print_r($match);
  5. }


 
EDIT : antislash...


Message édité par soju le 27-09-2005 à 14:55:22
Reply

Marsh Posté le 27-09-2005 à 14:55:28    

lol les assertions je n'y comprend rien, par contre c'est clair qu'il peut y avoir des virgulles, des apostrophes et tout dans les champs donc si cette solution fonctionne dans ces cas la je vais la prendre.
Merci bcp je vais essayer de comprendre comment ca marche :)

Reply

Marsh Posté le 27-09-2005 à 14:58:03    

Loizo a écrit :

lol les assertions je n'y comprend rien


l'assertion (?<!\\\\\\) est pour s'assurer que le ' ne sera pas précédé d'un \

Reply

Marsh Posté le 27-09-2005 à 15:00:24    

D'accord ! Ca reste obscure a regarder comme ca, mais en tout cas ca marche vraiment bien !

Reply

Marsh Posté le 27-09-2005 à 15:15:26    

En fait ouais ca pose probleme si par exemple dans un champ j'ai des virgules, il faudrai qu'il ignore les virgules qui ne sont pas entourées de '', car dans ce cas elles sont dans la valeur champ et ne servent pas a separer les nom de champs dans l'insert...

Reply

Marsh Posté le 27-09-2005 à 15:21:53    

En gros, il faut prendre les virgule qui ne sont pas dans une chaine de caractére SQL.
Une chaine de caractére est délimité par deux " (ou deux ' selon les cas)qui sont précédé par un nombre pair de \ .
Et il faut penser aussi aux noms de colones et de table ou de bases qui peuvent être délimité par deux ` sous mysql, [ et ] sous access ... En utilisant ces caractéres clés, on peut trés bien mettre une ( dans un nom de table, de base ou de colone (sic)

Reply

Marsh Posté le 27-09-2005 à 15:30:13    

Loizo a écrit :

En fait ouais ca pose probleme si par exemple dans un champ j'ai des virgules, il faudrai qu'il ignore les virgules qui ne sont pas entourées de '', car dans ce cas elles sont dans la valeur champ et ne servent pas a separer les nom de champs dans l'insert...


jai pas tout capté
par exemple avec insert into maTable values ('7,3','castor','po\\'llux',''); la regexp récupère bien 7,3 donc je ne vois pas le problème

Reply

Marsh Posté le 27-09-2005 à 15:32:38    

Et elle récupére aussi
po\'llux
en une seule fois?

Reply

Marsh Posté le 27-09-2005 à 15:35:59    

omega2 a écrit :

Et elle récupére aussi po\'llux en une seule fois?

oui, pratique les assertions  :)

Reply

Marsh Posté le 27-09-2005 à 15:38:47    

Et pour :

Citation :

insert into maTable values ('7,3','castor','po\\','llux','');


Il trouverait quoi?
 
EDIT : j'aurais bien testé moi même mais j'ai pas de php sous la main. :(

Message cité 1 fois
Message édité par omega2 le 27-09-2005 à 15:39:28
Reply

Marsh Posté le 27-09-2005 à 15:42:54    

omega2 a écrit :

Et pour :

Citation :

insert into maTable values ('7,3','castor','po\\','llux','');


Il trouverait quoi?

oui bien vu, ça ne marche plus  :(  

Reply

Marsh Posté le 27-09-2005 à 15:51:10    

soju a écrit :

jai pas tout capté
par exemple avec insert into maTable values ('7,3','castor','po\\'llux',''); la regexp récupère bien 7,3 donc je ne vois pas le problème


 
Ah ouais, bizzare j'ai trouvé un exemple ou ca buggait mais je ne le retrouve plus, tant pis :D

Reply

Marsh Posté le 28-09-2005 à 14:34:41    

C'est encore moi :D Donc j'ai encore un probleme en fait, je pensais que ca allait mais un cas vient de se présenter ou ca foire.
Donc j'essaye de recuperer sur quelle table on travaille (en regardant la requete j'extrait la table). Ca marchait tres bien avec ce type de requete :
 

Code :
  1. insert into maTable values ('73','castor','pollux','');


 
En faisant :
 

Code :
  1. if(preg_match("/^insert into (.+) values.*/i",$req,$table))


 
Je sais c'est ptet pas optimisé mais ca marche :D Ca me retourne bien 'maTable'...
 
Mais avec ce type de requete ca foire :
 
 

Code :
  1. insert into maTable (id_tab,nom_tab,type_tab) values ('73','castor','pollux','');


 
Bah ca marche plus, ca me retourne 'maTable (id_tab,nom_tab,type_tab)'
 
Et je n'arrive pas a ce que ca ne me recupere que maTable :/:(

Reply

Marsh Posté le 28-09-2005 à 14:44:15    

ben c'est normal, tu lui demande re te retourner tout ce qui est avant le "values". Il faut lui dire qu'il doit retourner tout ce qui est avant le premier "(" ou devant le premier "values" mais attention il faut faire ça sans tenir compte de ce qui est entre "`" (pour mysql, "[" et "]" pour access, bref à adapter)
 
J'espéres t'avoir mis sur la voie. :)

Reply

Marsh Posté le 28-09-2005 à 14:50:45    

Ouais c'est ce a quoi j'ai pensé, donc j'ai fais ca :
 

Code :
  1. if(preg_match("/^insert into (.+) \\(.*/i",$req,$table))


 
Donc la je lui dis tout ce qui est avant la prenthese, mais ca ne marche pas. Et puis de tte facon il peut ne pas y avoir de parenthese donc j'ai fais ca :
 

Code :
  1. if(preg_match("/^insert into (.+) \\(?.*/i",$req,$table))


 
Mais c'est pareil de toute facon, donc j'ai compliqué un peu plus en mettant tout mais c pareil :
 

Code :
  1. if(preg_match("/^insert into (.+) \\(?.*\\)? values.*/i",$req,$table))


 
Et bien sur ca ne marche pas non plus :D J'essaye de fonctionner linéairement, genre y a tel motif puis tel autre etc et j'essaye de le transformer en expression reguliere mais ca doit pas etre comme ca qu'on fait, en tout cas ca ne marche pas :/


Message édité par Loizo le 28-09-2005 à 14:51:26
Reply

Marsh Posté le 28-09-2005 à 14:53:46    

me rapelle plus exactement comment on fait en regexp, mais il y a moyen grace aux parentaises de dire ceci ou cela.
Ca doit être un truc du genre (\(|values)

Reply

Marsh Posté le 28-09-2005 à 14:56:01    

Ouais le OU | marche je l'ai utilisé a un moment.
J'ai deja testé mais ca foire :
 

Code :
  1. if(preg_match("/^insert into (.+) \\(|values.*/i",$req,$table))


 
Mais je pense que je m'y prend pas comme il faut...

Message cité 1 fois
Message édité par Loizo le 28-09-2005 à 14:56:58
Reply

Marsh Posté le 28-09-2005 à 15:08:27    

bon, c'est sans les mains, enfin aucune regexp n'a été maltraitée dans ce bout de code
c'est pas genre optimal, , c'est ultralinéaire, mais bon en 5 min ...
ya un minimum de gestion d'erreur, et ça marche ...
mais ça a besoin d'un format stricte, en tout cas pour les ','
et ça doit presque pouvoir gagner un prix d'obfuscation  :D  

Code :
  1. $query = "insert into maTable values ('73','cas\\'tor','pollux','');";
  2. // 1. on vire tout avant la 1ère parenthèse
  3. $pos = strpos($query, '(');
  4. if ($pos === false) die('mauvais format 1');
  5. $query = substr($query, $pos);
  6. // 2. on vire tout après la dernière parenthèse
  7. $pos = strrpos($query, ')');
  8. if ($pos === false) die('mauvais format 2');
  9. $query = substr($query, 0, $pos);
  10. // 3. vérifie qu'il reste qlq chose :)
  11. if (strlen($query) < 3) die('mauvais format 3');
  12. // 3.2 attention il nous reste (' devant et ' derrière, ça les enlève ...
  13. $query = substr($query, 2, -1);
  14. // 4. tranforme en tableau
  15. $query = explode("','", $query);
  16. // 5. ouala
  17. print_r($query);


 
[edit for code comments]


Message édité par shakpana le 28-09-2005 à 15:27:22
Reply

Marsh Posté le 28-09-2005 à 16:12:42    

ou en 2 étapes à preg
 
preg_match  
'/\(\'(.*)\'\)/'
 
preg_split
'/\'[ ]?,[ ]?\'/'
 
mais en une seule, dsl, pas encore ...


Message édité par shakpana le 28-09-2005 à 16:15:14
Reply

Marsh Posté le 28-09-2005 à 17:36:14    

Loizo a écrit :

Ouais le OU | marche je l'ai utilisé a un moment.
J'ai deja testé mais ca foire :
 

Code :
  1. if(preg_match("/^insert into (.+) \\(|values.*/i",$req,$table))


 
Mais je pense que je m'y prend pas comme il faut...


 
#^insert into ([^ ]+) (?:\(|values)#i


Message édité par sielfried le 28-09-2005 à 18:35:50

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 29-09-2005 à 09:15:31    

Nickel ca marche super ! Merci :jap:

Reply

Marsh Posté le 29-09-2005 à 09:31:38    

Il me semble que le "into" est facultatif dans un insert.

Reply

Marsh Posté le 29-09-2005 à 09:52:16    

Ah bon ?
De toute facon les requetes insert sur le site sont toutes deja mise avec des into donc je pense que c bon.
Mais je ne savais pas qu'on pouvait ne pas le mettre :o

Reply

Marsh Posté le 29-09-2005 à 10:14:06    

Dans mysql, en tout cas, c'est facultatif. Mais moi aussi je le met à chaque fois pour des questions de lecture de la requette. :)

Reply

Marsh Posté le 29-09-2005 à 14:07:24    

Ouais je fais pareil :)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed