Regexp embetante

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Regexp embetante

par jules » 10 janv. 2009, 13:48

Ahhh oui !! C'etait ca le problème..
Du coup le masque avec [[:space:]] fonctionne bien.
Merci bcp :)

par blof » 10 janv. 2009, 12:56

entre "td" et "width" il y a 2 espaces.

est-ce que ça peut expliquer ?

par jules » 10 janv. 2009, 12:25

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

par blof » 10 janv. 2009, 10:06

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. )

par jules » 10 janv. 2009, 00:21

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..

par Ryle » 08 janv. 2009, 12:25

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 :)

par jules » 07 janv. 2009, 21:07

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>

par jules » 07 janv. 2009, 20:45

Re,

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

par blof » 27 déc. 2008, 16:55

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 )

par Invité » 27 déc. 2008, 16:09

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é ?

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

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().

par Ryle » 27 déc. 2008, 12:33

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 :)

par jules » 27 déc. 2008, 03:35

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 :/

par Elie » 27 déc. 2008, 01:59

<?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 :)

par Ryle » 27 déc. 2008, 01:59

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 :)