Page 1 sur 1

regex répetition de classes

Posté : 03 août 2007, 18:01
par Invité
bonjour un petit problème de regex.

J'utilise une regex avec des parenthèse capturante du genre
preg_match ('#^(.*),"(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)"$#i',$val,$match);
mais bon on peut voir si on a pas trop les yeux qui louchent (à force je vous jure c'est fatiguant) qu'il y a un certain nombre de truc qui ce répète.

J'ai voulu utiliser une mééthode simple qui consiste à mettre en parenthèse le truc à répéter et à le faire suivre par un chiffre entre accolades.
preg_match ('#^(.*)(?:,"(.*)"){7}$#i',$val,$match);
Mais marche pas non plus. je sais plus comment faire.

Merci d'avance.

David.

Posté : 03 août 2007, 18:37
par Sékiltoyai
Pourquoi tu as mis ceci ?

Posté : 03 août 2007, 20:27
par Ripat
Tout d'abord, ça ressemble à un split sur la virgule. Auquel cas un explode() serait plus approprié que les regex.

Ensuite, si tu persistes dans la voie des regex, sache que les quantificateurs, comme *, sont gourmands par défaut dans les fonctions PCRE. Ton motif ne marchera donc jamais puisque le premier dot ira jusqu'à la dernière virgule.
Lis ceci et ceci.

Ou bien remplace tes .* par une classe négative [^,]* qui ne sera jamais gourmande.

Enfin, s'il s'agit de parser un gros fichier de données et que tu as la main sur le serveur, awk me semble l'outil idéal.

Posté : 03 août 2007, 21:27
par Sékiltoyai
Ou bien l'option u

Posté : 03 août 2007, 21:37
par Ripat
Ou bien l'option u
Option U plutôt. L'option u (minuscule) active le support UTF-8 dans PCRE.

Posté : 04 août 2007, 00:43
par Davee
Pourquoi tu as mis ceci ?
Ben j'ai lu que ?: évitait que les parenthèses soient capturante parce que la première parenthèse capture match[1] et la deuxième parenthèse capture match[2] et la troisième parenthèse (ouvrante j'entend) capture match[3]

En desespoir de cause je me suis dit pourquoi pas mettre ?: pour éviter que la deuxième capture, ça marche mais c'est pas pour autant qu'elle va me compter le chiffre entre accolade comme un répétiteur. (mais ça je le savais pas).
Tout d'abord, ça ressemble à un split sur la virgule. Auquel cas un explode() serait plus approprié que les regex.
Ben en fait les string contenu entre les guillemets ont quelques fois des virgules donc je peut pas utiliser explode.
en fait les données à traiter se composent sous forme de tableau

[0]=> 1," string "," string,string,string "," string "," string "," string "\n
[1]=> 2," string "," string,string,string "," string "," string "," string "\n
[2]=> 3," string "," string,string,string "," string "," string "," string "\n
[3]=> 4," string "," string,string,string "," string "," string "," string "\n
...etc

Voilà je na'i pas la main sur le serveur mais je peut traiter les données sur easyphp avant de les envoyer au server . awk tiens faut que je me penche dessus parce que connais pas.

'u' j'y avait pas pensé, à vrai dire c'était pas mon problem majeur mais vous avez raison de m'y faire penser. :)
Ripat: Merci pour les liens je les ai parcourru assez vite ce soir, je m'y remettrai demain il est bien trop tard 00:30 faut que je dorme si je veux me lever demain.
Sinon claviotterais au lit. ...

du verbe claviotter === signifie taper sur son clavier sans violence, ni colère. :D

Merci à tous bonne nuit.

David.[/b]

Posté : 04 août 2007, 01:02
par Ryle
Si jamais c'est d'un fichier que proviennent tes données, tu peux utiliser la fonction fgetcsv() qui sera parfaite pour cela. Suffit de lui spécifier que le séparateur est une virgule et que l'encadrant est une guillemet et il te fera un tableau tout seul :)

Et si c'est pas dans un fichier... ben c'est bien dommage, ça aurait été lpus simple ;)

Posté : 04 août 2007, 11:04
par Davee
fgetcsv une perle cette petite fonctions :)

J'ai rien eu à faire, un copier coller de l'exemple du manuel php.
$row = 1;
$handle = fopen("test.csv", "r");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
    $num = count($data);
    echo "<p> $num fields in line $row: <br /></p>\n";
    $row++;
    for ($c=0; $c < $num; $c++) {
        echo $data[$c] . "<br />\n";
    }
}
fclose($handle);
J'ai changer le nom de fichier (épuisant!)

Merci :)

David.

Posté : 04 août 2007, 12:28
par Ryle
Cool ! Bon ça aurait aussi pu se faire avec des expressions régulières s'il avait fallu, mais comme c'est un format assez classique de fihier csv (avec une virgule au lieu d'un point-virgule), j'ai bien fait d'essayer :) (d'où l'importance de donner le contexte et pas juste le problème ;))

Je rajoute le [Résolu] pour toi puisque tu n'étais pas connecté quand tu as posté le topic :)

Posté : 04 août 2007, 12:52
par Davee
(d'où l'importance de donner le contexte et pas juste le problème ;))
Oui c'est vrai totalement raison. C'est peut-être par souci de clareté , au début . :wink:

Mais c'est vrai quand même que j'aurais bien voulu savoir pourquoi ma regex ne marchait pas au niveau des répétitions. ( c'est pas pour être chiant mais bon !)
Je rajoute le [Résolu] pour toi puisque tu n'étais pas connecté quand tu as posté le topic :)

Merci j'ai changé de tactique, maintenant je me connect automatiquement. Voilà... peinard Gérard! :)

Merci
David.