Une petite aide sur une expression reguliere svp :))

Résolu
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005 - 18 oct. 2005 à 14:52
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005 - 19 oct. 2005 à 11:10
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 : (expliquée juste au dessus) :
"/<li>.*?\[ *testBDD *; *block *= *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 ))

25 réponses

hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005
19 oct. 2005 à 11:10
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!!!!
3
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
18 oct. 2005 à 15:05
celle-ci fonctionne : (?:</li>\s*)<li>.*</li>

Sébastien FERRAND
[MVP C#]
0
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005
18 oct. 2005 à 15:34
ca me retrourne l'erreure suivante :

<!--StartFragment --> Warning: Unknown modifier '<' in f:\action1 framework\index.php

peut tu m'expliquer :
(?:</li>\s*)

ca veut dire :
pas de </li> 0..n fois, suivit de <li>.*</li>
?

donc () indique une suite de char,
?: ->une negation
/s ->retours a la ligne possible
* -> 0..n fois

c'est bien ca?
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
18 oct. 2005 à 15:37
?: --> c'est non capture... mais ce n'est peut-être pas géré en php...

essaye : (</li>\s*)<li>.*</li>

et n'oublie pas de doubler les \ dans sinon ca marche pas !

Sébastien FERRAND
[MVP C#]
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005
18 oct. 2005 à 15:41
ps : j'utilise preg_match, utilisant PCRE "Expressions rationnelles compatibles Perl"

la notation est-elle la meme que celleque tu utilise?
utuilise tu POSIX?
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
18 oct. 2005 à 15:49
en C# les expressions régulières sont conformes à ECMA. donc je pense que ce sont les mêmes qu'en Perl.

pour en revenir à ton problème :
- as-tu pensé à doubler les \ dans ta chaine, sinon ils sont considérés comme caractères d'échappent.
- tu peux résoudre l'erreur Warning: Unknown modifier '<' in f:\action1 framework\index.php en ajoutant un \ devant les < et les >

Sébastien FERRAND
[MVP C#]
0
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005
18 oct. 2005 à 15:58
j'ai donc testé

<!--StartFragment --> (\<\/li>\s*)<li>.*\<\/li>

ca ne passe pas, toujours : <!--StartFragment --> Warning: Unknown modifier '<' in f:\action1 framework\index.php

bizaremment, quand j'utilisait :

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

ca ne me mettait pas cette erreure....

donc, pour resummer : j'echappe bien les "<" et les "/", mais j'ai un blocage sur les "<" quand meme...
sinon j'ai bien compris ta regex? (cf le post plus haut)
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
18 oct. 2005 à 16:01
essaye ca : (</li>\\s*)<li>.*</li>

Sébastien FERRAND
[MVP C#]
0
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005
18 oct. 2005 à 16:13
alors j'ai essayé a peu pres toutes les alternatives en finissant par :

"(\<\/li>\\s*)<li>.*\<\/li>"

mais ca ne veut pas passer, toujours l'erreure sur le "<"...
ton option /s est elle pour :

<DT>s (<VAR>PCRE_DOTALL</VAR>)
<DD>
Avec cette option, le méta-caractère point (.) remplace n'importe quel caractère, y compris les nouvelles lignes. Sans cette option, le caractère point ne remplace pas les nouvelles lignes. Cette option est équivalente à l'option Perl /s. Une classe de caractères négative telle que [^a] acceptera toujours les caractères de nouvelles lignes, indépendamment de cette option.

??

</DD>
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
18 oct. 2005 à 16:22
Ohlala vous allez finir pour vous grillez des neurones avec vos expressions régulières
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
18 oct. 2005 à 16:26
euh... je crois que tu interprètes mal la regex...

on reprend :

(<li>\s*) : <li> suivi de n'importe quel caractères d'espacement (\t \n \r ...), 0 ou plusieurs fois
<li>.*</li> : .* n'importe quel caractère 0 ou plusieurs fois.

pourrais-tu nous montrer ton code... même si c'est du php...

Sébastien FERRAND
[MVP C#]
0
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005
18 oct. 2005 à 16:36
alors, en fin de post, je t'ai mis ma fonction en entier... mais elle est mal commentée, el les variables mal nommées pour l'instant, suite a de nombreuses refactorisations...

le principe est le suivant :
ma fonctione recupere une ressource de resultat BDD, et une chaine disant quelle balise va etre "fusionnée" sans oublier le fichier source qui va etre modifié
Ensuite, elle recupere une balise de type : <!--StartFragment --> [testBDD;block = li]
de cette balise, elle extrait le block containeur
elle crée ensuite deux strings : et <\/block>
puis lance la regex posant le pb

function mergeDyn($indexBalise, $resultQuery) {
global $template;
dbgStore("on est dans MergeDyn", TEMPLATEDYN);
$motifBaliseBlock = "\[ *$indexBalise *; *block *= *([[:alnum:]]+) *\]";//ex : "[ balise1; block= toto]"
eregi($motifBaliseBlock, $template, $blockNom);//pas de while, un seul block multiple avec le meme index est géré
//recuperation de la balise correspondante trouvée
$baliseMere = $blockNom[0];
$blockNom = ($blockNom[1]);
$blockDebut = "<" . $blockNom . ">";
$blockFin = str_replace("<", "<\/", $blockDebut);
//extraction du block et céation de la var mergedBlock = ""
//"(?:$blockFin\s*)$blockDebut.*\[ *$indexBalise *; *block *= *$blockNom *\].*$blockFin";//ex : "<li>.\[ *testBDD *; *block *= *([[:alnum:]]+)* *]\].</li>"
$motifBlock = "(\<\/li>\s*)<li>.*\<\/li>";
var_dump($motifBlock);
preg_match($motifBlock, $template, $block);
$block = $block[0];
dbgStore("Bloc de travail : $block", TEMPLATEDYN);
$motifSousBalises = "/\[ *$indexBalise *; *([[:alnum:]_]+) *\]/";
preg_match_all($motifSousBalises, $block, $SousBalises, PREG_SET_ORDER);
//interrogation de la base
$mergedBlock = "";
while ($row = mysql_fetch_array($resultQuery, MYSQL_ASSOC ) ) {
//boucle de duplication par les valeur BDD
$blockEntraitement = $block;
foreach ($SousBalises as $SousBalise) { // ($i = 0; $i < count($tab2Balises); $i++) {
$blockEntraitement = str_replace($SousBalise[0],$row[$SousBalise[1]], $blockEntraitement);
}
$mergedBlock .= $blockEntraitement;
}
//reste a supprimmer la balise mere:
$mergedBlock = str_replace( $baliseMere, "", $mergedBlock);
//var_dump($mergedBlock);
//reinjection dans le template
$template = str_replace($block, $mergedBlock, $template);
}
0
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005
18 oct. 2005 à 16:39
a retenir :
$motifBlock = "(\<\/li>\s*)<li>.*\<\/li>";

preg_match($motifBlock, $template, $block);

ps : j'ai fait une erreure : [testBDD;block = li]
(testBDD n'est pas "en vert")
0
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005
18 oct. 2005 à 16:45
par contre, la regex que tu me preopose ne me semble pas bonne :

<!--StartFragment -->

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

<LI>[testL2P ;block = li] [testL2P; libele] </LI>
est un exemple de code posant probleme :
mon script gere tres bien le premier champ, mais pour le second li, il recupere en meme temps le premier... et mixe le tout...

d'apres ce que tu me propose, il trouverait tres bien le second car precedé d'un <li>
mais pour le premier? qui n'est precédé que d'un ??

c'est pour ca que je penchait vers ce genre de motif :

<li> suivit de tout saut <li> suivit de [testL2P ;block = li] suivit de </li>
si tu voit ce que je veut dire.
malheureusement, je ne sait pas comment coder "tout sauf <li>"

(^<li>) => ?? ne semble pas marcher...
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
18 oct. 2005 à 16:47
je sais maintenant pourquoi j'ai arrété le php : c'est illisible

en fait, je pense que le pattern tel que tu le renseignes ne fonctionne pas.
$motifBlock = "(\<\/li>\s*)<li>.*\<\/li>";

en php (comme en C, C++, C#, Java...), le \ est un caractère d'échappement... le problème c'est que là tu échappes le s dans \s*) ce qui ne veut plus rien dire.

Essaye ceci : $motifBlock = "(</li>\\s*)<li>.*</li>";

Sébastien FERRAND
[MVP C#]
0
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005
18 oct. 2005 à 16:49
il n'a pas prise mes liste, je reprend :

<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>
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
18 oct. 2005 à 16:53
sinon, la regex standard pour récupérer toutes les lignes de <li>

<li>(.*?)</li>

à toi maintenant de vérifier ce qu'il s'y trouve

Sébastien FERRAND
[MVP C#]
0
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005
18 oct. 2005 à 16:56
pourtant ce motif :
$blockDebut.*\[ *$indexBalise *; *block *= *$blockNom *\].*$blockFin";
fonctionnait tres bien... (si je puit dire)
c pas la faute du php, la c'est mas faute pour la presentation...
j'etait a la bourre, je l'ai progremmé en une soirée (tout un framework svp :))

en note la doc php, d'apres elle, il nedevrait pas y avoir de pb avec \s et \/ (qui fonctionne c'est certain)

Si la chaîne est entourée de guillemets doubles (<VAR>"</VAR>), PHP va comprendre certaines séquences de caractères :




Tableau 11-1. Les caractères spéciaux


<COLGROUP>
<COL>
<COL>

----

Séquence |
Valeur |

----

<VAR>\n</VAR>,
Nouvelle ligne (<VAR>linefeed</VAR>, LF ou 0x0A (10) en ASCII),
----

<VAR>\r</VAR>,
Retour à la ligne (<VAR>carriage return</VAR>, CR ou 0x0D (13) en ASCII),
----

<VAR>\t</VAR>,
Tabulation horizontale (HT ou 0x09 (9) en ASCII),
----

<VAR>\\</VAR>,
Anti-slash,
----

<VAR>\$</VAR>,
Caractère $,
----

<VAR>\"</VAR>,
Guillemets doubles,
----

<VAR>\[0-7]{1,3}</VAR>,
Une séquence de caractères qui permet de rechercher un nombre en notation octale.,
----

<VAR>\x[0-9A-Fa-f]{1,2}</VAR>,
Une séquence de caractères qui permet de rechercher un nombre en notation hexadécimale.


Si vous essayez d'utiliser l'anti-slash sur n'importe quelle autre séquence, l'anti-slash sera affiché dans votre chaîne.
0
Arthenius Messages postés 1182 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 6 septembre 2011 14
18 oct. 2005 à 17:20
heu

et si au lieu de passer par des expressions reguliere tu faisais un programme a la main a l'ancienne qui te parcourt ton bout de code avec les <li> et que tu extrait exactement ce que tu veux ?????

en testant les caracteres.. ??




<HR>
Arthenius
http://blogs.developpeur.org/Arthenius/

"Ce qui ne me tue pas, me rend plus fort..."
0
hansap Messages postés 23 Date d'inscription vendredi 10 juin 2005 Statut Membre Dernière intervention 19 octobre 2005
18 oct. 2005 à 17:30
ce que j'ai du mal a comprendre, c'est que mon expression me semble juste...

totu d'abord, elle cpature bien ce qu'il faut.
secondement son pb est qu'elle est greedy (gourmande).

hors j'utilise l'option //U qui la rend non gourmande...

ce qui marche d'ailleur... mais par pour l'autre...
"/$blockDebut.*\[ *$indexBalise *; *block *= *$blockNom *\].*$blockFin/sU"
= >
"/<li> \[ *testBDD*; *block *= *li*\].* <\/li>/sU"

...
d'ailelur si je fait :
"/$blockDebut.*?\[ *$indexBalise *; *block * = *$blockNom *\].*?$blockFin/s"
j'ai le meme pb, ne serait-ce pas un bug de preg_match?
0
Rejoignez-nous