Expressions régulières - Parser du template HTML

Petit nouveau ! | 8 Messages

12 avr. 2010, 10:39

Bonjour à tous,

ceci est mon premier message alors bonjour et merci d'avance pour les échanges que j'aurais ici.

J'entre directement dans le vif du sujet !

Je suis actuellement en train de bosser sur mon petit framework PHP perso, dans le but d'avoir ma solution maison pour réaliser mes projets.
Deux des aspects du boulot sont :
- Gestion de templates
- Contenu géré par plugins

J'en arrive à une phase un peu compliqué dans le développement, puisque je n'avais encore jamais eu à manipuler les expressions régulières.

En gros, le soucis est le suivant :
J'ai des modèles de templates, des documents HTML correspondant au corps des pages générées par le programme.
Dans ce document template, j'ai des "pseudo-balises", comme par exemple !%!MENU!!%. C'est à cet endroit que le programme insèrera le menu par exemple.

L'idée est donc de repérer ces "pseudo-balises" et connaitre leur contenu.

Pour débuter, j'utilise un bête script de test.

Le soucis, c'est que je n'arrive pas à comprendre comment récupérer ce dont j'ai besoin.

Code : Tout sélectionner

<?php $texte='Je suis !%!CONTENTU!!% trzès content !%!CONTENTE!!% et puis !%!MENUHGYG!!%'; preg_match_all("(!%!.{8}!!%)",$texte,$solution1); preg_match_all("(!%!(.*)!!%)",$texte,$solution2); preg_match_all("(!%!(.*[^ ])!!%)",$texte,$solution3); preg_match_all("(!%!(.*[^o])!!%)",$texte,$solution4); //juste un test pour exclure les o foreach($solution1[0] as $a) echo "\n".$a."\n"; //fonctionne bien mais ça m'oblige à avoir toujours 8 caractères dans ces pseudobalises foreach($solution2[0] as $a) echo "\n".$a."\n"; //affiche !%!CONTENTU!!% trzès content !%!CONTENTE!!% et puis !%!MENUHGYG!!% foreach($solution3[0] as $a) echo "\n".$a."\n"; //affiche la même chose foreach($solution4[0] as $a) echo "\n".$a."\n"; //affiche la même chose également, les o ne sont pas exclus. ?>
J'en arrive à un point ou j'aurais vraiment besoin d'un coup de main.

Merci d'avance !


Tom

ViPHP
ViPHP | 5462 Messages

12 avr. 2010, 10:43

!%!(\w+)!!%

?

Petit nouveau ! | 8 Messages

12 avr. 2010, 10:47

Je ne le connaissais pas, malheureusement il ne me renvois rien :s

Code : Tout sélectionner

<?php $texte='Je suis !%!CONTENTU!!% trzès content !%!CONTENTE!!% et puis !%!MENUHGYG!!%'; preg_match_all("!%!(\w+)!!%",$texte,$solution); foreach($solution[0] as $a) echo "<br />".$a."<br />"; ?>

ViPHP
ViPHP | 5462 Messages

12 avr. 2010, 10:56

tu devrais avoir une erreur d'afficher si tu fais ca, affiche les
preg_match_all('/!%!(\w+)!!%/u',$texte,$solution);

Petit nouveau ! | 8 Messages

12 avr. 2010, 10:58

Bah voilà, c'est exactement le code que je viens de trouver !

Code : Tout sélectionner

<?php $texte='Je suis !%!CONTENTU!!% trzès content !%!CONTENTE!!% et puis !%!MENUHGYG!!%'; echo preg_match_all("(!%!(\w+)!!%)",$texte,$solution); print_r($solution); foreach($solution[0] as $a) echo "<br />".$a."<br />"; ?>
ça a l'air de fonctionner parfaitement !

je vais passer ma matinée à tester la solution tiens !

Merci ;) je vous donne des nouvelles du choses rapidement ;)

ViPHP
ViPHP | 5462 Messages

12 avr. 2010, 11:02

je pense que preg_replace_callback devrais t'intéresser :wink:

ViPHP
ViPHP | 4039 Messages

12 avr. 2010, 11:05

Il faudrait penser à utiliser un délimiteur correct dans tes expressions.

Sinon, l'option des expressions régulières n'est pas très performante (d'accord, elle est facile à mettre en place, mais elle est lente à l'usage). Donc si un solution plus performante t'intéresse, je ferais le traitement en brut, en utilisant des strpos() par exemple.
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Petit nouveau ! | 8 Messages

12 avr. 2010, 11:07

@stealth35

Effectivement, merci :D
ça m'embêtait effectivement d'aller vers un double traitement ! (rechercher, traiter et enfin remplacer)
ça va me faire un contrôleur à créer pour les plugins. Ça me semble propre.

@Berzemus
tu parles du slash mis par stealth35 et que je n'ai pas mis moi ?

ViPHP
ViPHP | 5462 Messages

12 avr. 2010, 11:14

Sinon, l'option des expressions régulières n'est pas très performante (d'accord, elle est facile à mettre en place, mais elle est lente à l'usage). Donc si un solution plus performante t'intéresse, je ferais le traitement en brut, en utilisant des strpos() par exemple.
pour ce genre de chose non, le coup du strpos ca va être une catastrophe et en plus pas compatible UTF-8

ViPHP
ViPHP | 4039 Messages

12 avr. 2010, 11:17

@Berzemus
tu parles du slash mis par stealth35 et que je n'ai pas mis moi ?
Délimiteurs

Lors de l'utilisation des fonctions PCRE, il est nécessaire que le motif soit encadré par des délimiteurs. Un délimiteur peut être n'importe quel caractère alpha-numérique autre qu'un backslash ou qu'un espace.
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

ViPHP
ViPHP | 5462 Messages

12 avr. 2010, 11:19

mais non c'est correct, c'est pas pareil que les autres caractères
vous pouvez utiliser les délimiteurs (), {}, [], et <>, comme en Perl.
http://fr2.php.net/manual/fr/intro.pcre.php
En complément des délimiteurs cités ci-dessus, il est aussi possible d'utiliser des parenthèses comme délimiteur où les parenthèses ouvrante et fermante sont respectivement les délimiteurs ouvrant et fermant.
http://fr2.php.net/manual/fr/regexp.ref ... miters.php

Petit nouveau ! | 8 Messages

12 avr. 2010, 11:27

Bon alors je me suis lancé dans la fonction preg_replace_callback et il y a un truc qui me chiffonne.

J'ai commencé à aller vers ma structure objet maintenant que j'ai testé ma fonction. Du coup j'ai fait ce code :

Code : Tout sélectionner

<?php $texte='Je suis !%!CONTENU!!% trzès content !%!HEADER!!% et puis !%!MENU!!%'; class test { public function __construct($texte) { preg_replace_callback("/!%!(\w+)!!%/","test::traiteresult",$texte); } public function traiteresult($solutions) { switch($solutions[1]) { case('CONTENU'):echo'ici le contenu de la page';break; case('MENU'):echo'accueil - histoire - contact';break; default:echo"je ne connais pas cette fonction";break; } } } $allez = new test($texte); ?>
Ce qui me pose soucis, c'est la manière d'appeler le callback : preg_replace_callback("/!%!(\w+)!!%/","test::traiteresult",$texte);
Déjà utiliser les double deux points :: plutôt que ->.
Ensuite le fait de faire référence au nom de la classe plutôt qu'à l'objet : logiquement, on aurait du faire this->traiteresult.

Quelque chose m'échappe ?

ViPHP
ViPHP | 4039 Messages

12 avr. 2010, 11:29

mais non c'est correct, c'est pas pareil que les autres caractères
Je le sais parfaitement, mais je trouve la pratique à déconseiller: c'est moins clair, et on se demande toujours s'il faut ou non les échapper.

Alors voilà, je conseille l'utilisation des délimiteurs '#' (puisque Php le privilégie) et '/' (puisque historiquement, c'est ainsi que les expressions régulières sont délimitées, et qu'on retrouve la même notation dans les autres langages (Js, Perl, ...).

Notre rôle n'est pas seulement de trouver une solution aux problèmes posés (pour ça, une recherche sur le web suffit quasi tout le temps), mais aussi d'apporter un avis, un conseil, bref, d'établir une relation d'humain à humain, l'essence même d'un forum.
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Petit nouveau ! | 8 Messages

12 avr. 2010, 11:30

Notre rôle n'est pas seulement de trouver une solution aux problèmes posés (pour ça, une recherche sur le web suffit quasi tout le temps), mais aussi d'apporter un avis, un conseil, bref, d'établir une relation d'humain à humain, l'essence même d'un forum.
Et merci pour ça ;)

ViPHP
ViPHP | 5462 Messages

12 avr. 2010, 11:31

t'es pas obliger d'utiliser une class pour faire ca
sinon pour les info du type callback c'est par ici : http://fr2.php.net/manual/fr/language.p ... s.callback