Page 1 sur 2

Regexp embetante

Posté : 26 déc. 2008, 23:38
par jules
Bonsoir,

Je suis embêté par une vilaine Regexp.
Je voudrais récupérer le XXX dans ce code html là :

Code : Tout sélectionner

<tr class="black"> <td width="90%"> AAA </td> <td> XXX </td> </tr>
où :
AAA est une chaine de caractère fixe (10 caractères si ça peut aider..)
et XXX est ce que je veux récupérer.

J'ai essayé :
preg_match_all("#<td width=\"90%\">(0-9A-Za-z){10}</td><td>(.*)</td>#s", $page, $bordel);
J'ai ajouté l'option "s" pour que le CRLF soit inclu.
Mais évidement mon tableau $bordel est vide..

Merci pour votre aide.

Posté : 26 déc. 2008, 23:39
par jules
J'ai oublié de préciser à ceux qui pourraient me dire "récupère ce qu'il y a entre <td> et </td>" que des <td> il y en a plein la page.. :s

Posté : 27 déc. 2008, 01:59
par Ryle
Hmmm... tu n'as pas bien compris le fonctionnement de l'option "s" dans les expression régulières. Elle ne permet pas d'ignorer les retours à la ligne, mais de dire que le caractère "." qui remplace n'importe quel caractère, peut également remplacer les retours à la ligne. Ca ne t'empêche pas de devoir le spécifier dans ton masque :)
preg_match_all("#<td width=\"90%\">([0-9A-Za-z]{10})</td>.*<td>(.*)</td>#s", $page, $bordel);
J'en ai profité pour réajuster parenthèses et crochets autour de la chaine AAA, mais ne connaissant pas le besoin ou la structure de la chaine, ce sera sans doute à revoir :)

Posté : 27 déc. 2008, 01:59
par Elie
<?php

$code = '<tr class="black">
     <td width="90%"> AAA </td>
     <td> XXX </td>
</tr>';

preg_match_all("#<td>(.*)</td>#s", $code, $bordel);

print_r($bordel[1][0]);
            

?> 
Tout simplement :)

Je suppose que il y aura une condition que j'aurais pas pris en compte :)

Posté : 27 déc. 2008, 03:35
par jules
Tout simplement :)
Je suppose que il y aura une condition que j'aurais pas pris en compte :)
Oui, car ma variable "$code" contient toute une page en réalité avec plein de <td>..
preg_match_all("#<td width="90%">([0-9A-Za-z]{10})</td>.*<td>(.*)</td>#s", $page, $bordel);
Merci bien pour ton aide et la précision (importante!) pour l'option 's'.
Cela ne fonctionne toujours pas. J'ai essayé de mettre le 'vrai' texte à la place de ([0-9A-Za-z]{10}) pour voir si l'erreur venait de là ou pas, et effectivement mon tableau est toujours vide
(expression de test :
preg_match_all("#<td width="90%">abcdefghio</td>.*<td>(.*)</td>#s", $page, $bordel);
Le tableau de sortie est vide, pourtant ca l'air de coller :/

Posté : 27 déc. 2008, 12:33
par Ryle
euh.... t'as modifié le masque là.... en gros, tu dis que tu cherches une chaine avec "abcdefghio" dans ton code, et pas avec 10 caractères quelconque pour le "AAA" ....

Est-ce que tu pourrais nous donner un ou deux exemple du code original (celui que tu veux récupérer). Juste les zones concernées, mais avec les vraies valeurs à la place des AAA et XXX :)

Posté : 27 déc. 2008, 13:00
par blof

Code : Tout sélectionner

<tr class="black"> <td width="90%"> AAA </td> <td> XXX </td> </tr>
où :
AAA est une chaine de caractère fixe (10 caractères si ça peut aider..)
(0-9A-Za-z){10}
Il y a 2 espaces qui encadrent la fameuse chaîne de caractères ...
... et ils n'apparaissent pas dans le motif de l'expression régulière.

Je ferais quelque chose comme ça :
<pre>
<?php

$page = '<tr class="black">
     <td width="90%">abcdefghio</td>
     <td> XXX </td>
     <td> aaa </td>
     <td> bbb </td>
</tr>';

preg_match_all('#<td width="90%">[0-9A-Za-z ]{10}</td>.*<td>(.*)</td>#Us', $page, $v); 

//echo $v[1][0];
print_r($v);
?>
</pre>
( sans l'option U ( ungreedy / non gourmand ), et avec ce motif, ça ne marche pas )

et si il y a une seule valeur à récupérer, il vaut mieux utiliser preg_match() plutôt que preg_match_all().

Posté : 27 déc. 2008, 16:09
par Invité
Merci bien pour code blof, effectivement avec ton code cela fonctionne bien, avec

Code : Tout sélectionner

<td width="90%">abcdefghio</td>
(c.a.d collé aux balises) mais PAS avec un espace avant et apres la chaine comme j'avais écrit :

Code : Tout sélectionner

<td width="90%"> abcdefghio </td>
Voici un exemple concret Ryle :

Code : Tout sélectionner

<tr class="black"> <td width="90%"> C1C93AA443 </td> <td> Petit_Atelier </td> </tr>
(ce sont des références)

Pourquoi le masque #<td width="90%">[0-9A-Za-z ]{10}</td>.*<td>(.*)</td>#Us
ne prend-il pas en compte l'espace pourtant spécifié ?

Posté : 27 déc. 2008, 16:55
par blof
Pourquoi le masque #<td width="90%">[0-9A-Za-z ]{10}</td>.*<td>(.*)</td>#Us
ne prend-il pas en compte l'espace pourtant spécifié ?
parce qu'il y a 12 caractères entre les balises "td" :wink:

donc soit :
#<td width="90%">[0-9A-Za-z ]{12}</td>.*<td>(.*)</td>#Us
soit :
#<td width="90%"> [0-9A-Za-z]{10} </td>.*<td>(.*)</td>#Us
( dans ce cas il ne doit pas y avoir d'espace dans la chaîne )

Posté : 07 janv. 2009, 20:45
par jules
Re,

Désolé, aucun des deux masques ne fonctionne. Mon tableau reste vide :/

Posté : 07 janv. 2009, 21:07
par jules
Je vois pourquoi..
Y'a des tabulations avant ma référence, ce qui est invisible quand je le copie colle ici.
en gros ca fait :
<td width="50%">
(saut à la ligne)(6 tabulations)abcdefijre
(saut à la ligne)(5 tabulations)</td>

Posté : 08 janv. 2009, 12:25
par Ryle
Ben tu as la réponse à ta question... le masque s'applique à la chaine telle qu'elle présente dans le fichier source, il te faut donc faire un masque qui prenne en compte les retours à la ligne, les tabulations et les espaces éventuels :)

Si tes sauts de lignes sont toujours au même endroit, et que tu as toujours le même nombre de tabulations, tu peux les ajouter dans ton masque caractère par caractère (au début et à la fin, en fait partout où tu en a besoin :)).

Tu peux aussi spécifier le nombre d'occurence de la tab si celui-ci varie : "\t{0,6}" pour en avoir de 0 à 6 et éviter de le répéter 6 fois alors qu'il pourrait n'y en avoir que 5 de temps à autre etc.

Enfin, tu peux également utiliser la classe [[:space:]] dont je te laisse le soin de découvrir les effets et l'intéret dans ton cas :)

D'une manière générale, les expressions régulières ne sont pas bien compliquées à mettre en oeuvre, il te faut simplement trouver le masque qui colle parfaitement à ta chaine, et ce en toute circonstance :)

Posté : 10 janv. 2009, 00:21
par jules
Merci pour tes conseils !

Alors j'ai essayé :
- avec la classe :space: qui englobe d'après ce que j'ai lu les \r \n et \t
preg_match_all('#<td width="90%">[[:space:]]*[0-9A-Za-z]{10}[[:space:]]*</td>[[:space:]]*<td>(.*)</td>#Us ', $page, $bordel);  
- et la manière statique, en précisant le nombre exact de tabulations
preg_match_all('#<td width="90%">\r\n\t\t\t\t\t\t[0-9A-Za-z]{10}\r\n\t\t\t\t\t</td>\r\n\t\t\t\t\t<td>(.*)</td>#Us ', $page, $bordel);  
Mais aucun des deux masques n'est valide. Peut etre que je les utilise mal ?!
J'ai vu aussi que dans certains codes des personnes utilisent les codes hexadécimaux (comme 09 pour \t) dans leurs masques. Ca n'avait pas l'air de changer quoique ce soit pour moi..

Posté : 10 janv. 2009, 10:06
par blof
Salut,

bientôt 15 jours ...
... c'est trop.

Peux-tu faire un vrai copié/collé de ta chaîne de caractères ?
( ne saisis pas de mémoire ce que tu penses que ça pourrait éventuellement être. )

Posté : 10 janv. 2009, 12:25
par jules
Lut,
Voilà donc un vrai copié/collé,
Les sauts à la ligne ont été gardés, j'ai donc rajouté ce qui avait disparu : les tabulations.

Code : Tout sélectionner

<td width="90%"> (6 tabulations) AX2987HH00 (5 tabulations) </td> (5 tabulations) <td> (5 tabulations) Epautre_C6 (5 tabulations) </td>
Et au final je coudrais récupérer "AX2987HH00 => Epautre_C6"
Merci