Expression reguliere fort hardue!

Résolu
Signaler
Messages postés
23
Date d'inscription
vendredi 10 juin 2005
Statut
Membre
Dernière intervention
19 octobre 2005
-
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
-
http://www.developpez.net/forums/viewtopic.php%3Ft%3D406330%26start%3D15' target='_blank'>http://www.developpez.net/forums/viewtopic.php?t=406330&start=15
si vous voulez bien m'aider... :)

pour reprendre la problemeatique :
(copier coller de mon post sur developpez.net)

j'ai créé, pour une action de BTS, un moteur de template.
une de ses fonctionnalitées est de substituer un "bloque" par "autre
chose" (pas important ici)
pour substituer ce block, je doit tout d'abord l'extraire, pour ce
faire, je fait un preg_match() qui me retourne mon block, je fait mes
traitemeznts, puis je fait un str_replace() pour substituer le nouveuax
block.

mon pb se situe au niveau du preg_match :
cette fonction accepte trois parametre.
L'un d'eux est une expression reguliere.

cette expression est :
"/<li>.*?\[ *testBDD *; *block *= *li *\].*<\/li>/sU"
pour simplifier, on peut la noter :
"/<li>.*?.*<\/li>/sU"

mon pb :

au lieu de prendre le dernier <li> disponible, elle prend le
premier...cad :
Code:

<li> ne pas me prendre mias quand meme pris </li>
<li> je veut cette partie </li>
<li> ne pas me prendre et ca marche </li>


donnera :
Code:
<li> ne pas me prendre mias quand meme pris </li>
<li> je veut cette partie </li>


alors que je ne veut que :
Code:

<li> je veut cette partie </li>

meric de votre aide svp ))

16 réponses

Messages postés
23
Date d'inscription
vendredi 10 juin 2005
Statut
Membre
Dernière intervention
19 octobre 2005

Ca marche !!!!


"/<li>(.(?<!<li>))*\[ *testBDD *; *block *= *li *\].*<\/li>/sU"


telle est le type de motif qui fonctionne!
en versino simplifée :


"/<li>(.(?<!<li>))*.*<\/li>/sU"


MERCI A TOUS!!!!
Messages postés
9433
Date d'inscription
mardi 9 octobre 2001
Statut
Membre
Dernière intervention
13 avril 2007
9
Salut,



je ne comprends pas ton problème. Partons d'un fichier html, que
veux-tu parser et retourner ? (ça sera plus simple à comprendre je
pense)



a +

<hr size="2" width="100%"><li>Entraide, dépannage et vulgarisation informatique : Mon site de vulgarisation informatique</li>
Messages postés
23
Date d'inscription
vendredi 10 juin 2005
Statut
Membre
Dernière intervention
19 octobre 2005

conanit tu les moteur de template?
je veut en faire un moi meme.
cad :
tu as deux parties:
une page HTML (purement fixe)
un script PHP (purement dynamique)

a partir du script qui se debrouille pour recupérer des infos (requetes ou autre) tu fusionne les données dand ton template.

cad :
la ou tu n'avait qu'une balise [balise; client.nom]
tu auras tous les noms de tes clients...

dans mon pb :

j'ai une balise [balise; block = li] suivit de balsies du type [balise; client .nom]
pourquoi la rpemiere. car la ou il n'y avait qu'une seule balise, vont apparaitre plein de nom de client... faut bien savoir par ou les separer... et bien la le separateur (le "block") sera un <li>...</li>

donc, a partir de tout mon fichier HTML chargé dans une varible chaine de caractere, je veut pouvoir retrouver <li> bla bla bla </li>

et le bon...
si tu n'a pas compris va sur :
http://www.developpez.net/forums/viewtopic.php%3Ft%3D406330%26start%3D15' target='_blank'>http://www.developpez.net/forums/viewtopic.php?t=406330&start=15
stp :) j'ai passé plusieurs post a expliquer le pourquoi du comment :))
Messages postés
1406
Date d'inscription
mercredi 17 août 2005
Statut
Membre
Dernière intervention
28 août 2007
9
hansap => Connais tu le XLS ? Sorte de règle transformation des fichier XML (dont HTML fait parti)...







Tu écrit ta règle XLS, Tu colle ton XML dans une moulinette sous l'égide du XLS. Il en ressort un nouveau XML...







Sinon, je suis comme Antho : problème de compréhension, même en allant voir sur developpez.net.



Pour isoler le contenu des <li> ici </li> :

$matches= array();

preg_match_all("@<li>((\w|\s)*)</li>@", $matches, $text_html);

echo nl2br(print_r($matches,true));






Autrement, je te propose tout ça :



L'ordre est tel que <var>$matches[0]</var> est un tableau qui
contient les résultats qui satisfont le masque
complet, <var>$matches[1]</var> est un tableau qui contient les
résultats qui satisfont la première
parenthèse capturante, etc.
[salut.html clique moi]
partie 1 : [salut.html
partie 2 : clique moi
partie 3 : ]
Messages postés
9433
Date d'inscription
mardi 9 octobre 2001
Statut
Membre
Dernière intervention
13 avril 2007
9
Merci je sais ce qu'est un moteur de template, et malgré ton post sur
developpez.com je n'en comprends pas vraiment plus... m'enfin bon tant
pis. Bon courage.



a +

<hr size="2" width="100%"><li>Entraide, dépannage et vulgarisation informatique : Mon site de vulgarisation informatique</li>
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
42
xslt est bien plus approprié pour ce genre de choses...

In a dream, I saw me, drop dead... U was here, U cried... It was just a deam, if I die, U won't cry, maybe, U'll be happy

http://coucou747.hopto.org
Messages postés
23
Date d'inscription
vendredi 10 juin 2005
Statut
Membre
Dernière intervention
19 octobre 2005

bonjours J_G, j'ai lut avec une (tres) grande attention tout ce que tu m'a dit, mais avant tout, je vait essayer d'exposer un pb tres simple :

je fait :
<?
$chaine = "
<li> ne pas me prendre mais quand meme pris </li>
<li> je veut cette partie </li>
<li> ne pas me prendre et ca marche </li> ";
preg_match("/<li>.*je veut cette partie.*<\/li>/sU", $chaine, $occurence);
var_dump($occurence);
?>
et j'obtient :
<!--StartFragment -->array(1) { [0]=&gt; string(86) "<li> ne pas me prendre mias quand meme pris </li> <li> je veut cette partie </li>" }

donc, la ou je ne devrait avoir que la ligne du milieu, j'aen ai deux...
bug de preg_match?

Je pense donc etre en presence d'un bug... je suis en php 4.2.3, qi kkun pouvait essayer de reproduire ce petiti code pour moi...
merci anthomicro, j'ai ete un peu sec, dsl...
et coucou747 (ainsi que J_G) pensez vous que ce pourrait etre faisable de facon claire et conscise avec XSLT?
je presente ca pour une action BTS, et la presentation doit primer sur l'optimisation, je pense...
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
25
Hello,



je peux ?

Hansap, je ne comprends pas moin non plus complètement. Tu as 3 balises
<li>, et tu veux le contenu de la seconde, dans ton dernier
exemple...?



Quelle est la règle pour ton moteur ? Tu dois avoir des spécs, je suppose, donne les.



Ensuite...html, ça vient du sgml. xml aussi. xhtml aussi, donc.

Bref, la seule différence notable entre le html, et xml, c'est qu'html n'est pas sensible à la casse, xml si.

Mais la structure es la même.



Donc, quand je lis que xslt peut t'apporter une solution...je soutiens :-) Mais tu n'as peut-être pas besoin de passer par xslt.

En fait ce qui devrait t'intéresser, c'est XPath. Tu peux 'en servir
dans un fichier xsl...c'est pratique, et efficace. TU accèdes au noeud
que tu veux, à sa valeur, attribut, tu peux boucler sur tes noeuds
etc...si tu veux le 3ème <li> sur une liste de deux, ça va te
prendre 1 ligne en XPath.

Et en plus, tu peux 'en servir directement avec php.

Cherche XPath, XSLT, sur le web, et XPath sur php.net aussi.
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
25
Quant à ton expression régulière (j'ai oublié entre temps lol), ce
n'est pas un bug de preg_match, mais ton expression qui est fausse.



<?php

$chaine = "

<li> ne pas me prendre mais quand meme pris </li>

<li> je veut cette partie </li>

<li> ne pas me prendre et ca marche </li> ";

preg_match("/<li>*[je veut cette partie]*<\/li>/sU", $chaine, $occurence);

var_dump($occurence);

?>
Messages postés
23
Date d'inscription
vendredi 10 juin 2005
Statut
Membre
Dernière intervention
19 octobre 2005

JG :
Pour isoler le contenu des <li> ici </li> :
$matches= array();
preg_match_all("@<li>((\w|\s)*)</li>@", $matches, $text_html);
echo nl2br(print_r($matches,true));

effectivement, ca marche, cependant, tu travail sur un char unique : (\w|\s)* qui se repete tantque pas </li> (bizarre, ici y'a pas a echapper le "/"... un effet des "@"?? )

je pourrait essayer de fonctionner avec qqchose du genre de ((?!maChaine)|\w|\s) mais jusqu'a present... ca marche pas...
merci de ta piste...
Messages postés
23
Date d'inscription
vendredi 10 juin 2005
Statut
Membre
Dernière intervention
19 octobre 2005

malalam, tu me propose cette syntaxe :
preg_match("/<li>*[je veut cette partie]*<\/li>/sU", $chaine, $occurence);

!!! mais sa marche!

merci :)

par contre, maintenant, j'essaie de l'adapter a mon vrai masque de recherche :

"/$blockDebut.*[\[ *$indexBalise *; *block *= *$blockNom *\]].*$blockFin/sU"

non! ne fuit pas! je peut le simplifier!

"/<li>.*[\[balise;block=li\]].*<\/li>/sU"

ou encore :

"/<li>.*[\[balise\]].*<\/li>/sU"

en sachant qu'a l'origine :
"/<li>.*\[balise\].*<\/li>/sU"
etait ma syntaxe...

le pb etant que en rajoutant les crochets... et bien ca me trouve n'importe quelle ligne :'(

je suis tetu, mais le xpath... lors de l'examen, ils vont vraiment rien y comprendre!
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
25
Un prof qui ne comprend rien est un prof épâté (quand ça marche, évidemment, lol).



Bon...

Donne un exemple de chaine (tes vraies données cette fois, mais sans
les variables hein, mets en dur, ce sera plus simple), et ton
expression régulière

(enfin ça, ça va, on l'a ici). On va faire des tests :-) Parce que j'ai
vraiment du mal à me rendre compte dans tes simplification ce que tu
cherches.



Parce que ça, moi,

"/<li>.*[\[balise;block=li\]].*<\/li>/sU"

ça me laisse perplexe, lol.



Tu cherches à récupérer "[balise;block=li]" ?
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
25
"/$blockDebut.*[\[ *$indexBalise *; *block *= *$blockNom *\]].*$blockFin/sU"



Pourquoi les * entre tes variables ?
Messages postés
23
Date d'inscription
vendredi 10 juin 2005
Statut
Membre
Dernière intervention
19 octobre 2005

alors, un exemple d'HTML recherché :
----------------------------
<li>
[testBDD;block = li]
nom : [testBDD; nom] et id_outil =&nbsp;[testBDD; descriptif ] , enfin, l'activitée est : [ testBDD ;libele]
</li>



<li class="Style1">
[testL2P ;block = li]
[testL2P; libele]
</li>


--------------------------


Comme vous pouvez le voir j'ai deux "balises" differentes :


[testBDD;block = li]
et
[testL2P ;block = li]

les motif de regex sont :
"/<li>.*[\[ *testBDD *; *block *= *li *\]].*<\/li>/sU"
et
"<!--StartFragment -->/<li>.*[\[ *testL2P *; *block *= *li *\]].*<\/li>/sU"

pour le premier ca marche, pour le second, ca ne marche pas (il capture aussi le premier <li>)

ps : j'ai des " *" (espace etoile) car cela permet une notation plus "libre" au niveau du HTML...
Messages postés
23
Date d'inscription
vendredi 10 juin 2005
Statut
Membre
Dernière intervention
19 octobre 2005

stop!
je me susi trompé!
a force de faire des tests...

donc les motifs sont :
"<!--StartFragment -->/<li>.*\[ *testBDD *; *block *= *li *\].*<\/li>/sU"
et
"<!--StartFragment -->/<li>.*\[ *testL2P *; *block *= *li *\].*<\/li>/sU"

et le HTML :

<li>
[testBDD;block = li]
nom : [testBDD; nom] et id_outil =&nbsp;[testBDD; descriptif ] , enfin, l'activitée est : [ testBDD ;libele]
</li>



<li>
[testL2P ;block = li]
[testL2P; libele]
</li>
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
25
Bravo :-)