IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Preg_replace, remplacement PHP [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 99
    Par défaut Preg_replace, remplacement PHP
    Bonsoir à tous,

    Après multitude de tests, multitude de recherches, me voici ici. J'ai parcouru un peu la section du forum afin de voir les problèmes récurrents et voir si le mien en faisait partie. Mais, malheureusement, je ne l'ai pas vu.

    J'aimerai réalisé un truc très simple. Je prends un exemple, et qui n'est pas exactement ma ligne de code, mais cela illustrera le soucis, et si il se règle, il va de soi que je trouverais le moyen de faire de même avec mon code.

    J'ai un fichier .tpl, dans lequel est inclus ceci: [IF a > 3] Plus grand [ELSE] Plus petit [ENDIF]

    Le principe étant que lorsque je traite cette ligne, cela devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <?php if($a>3) { echo "Plus grand"; } else { echo "Plus petit"; } ?>
    Je veux donc transposer le pseudoCode de base via du code PHP. Voici le hic, ... je récupère bien la ligne, les éléments via les patterns et tout... mais il semblerait que le fait d'ajouter au début de mon remplacement aie l'effet d'ajouter <nom_de_balise et donc, il se perd en HTML et en restitution du fichier par la suite.

    Existe-il un moyen pour moi, au moment du parsage du template, de modifier ce pseudoCode via du code PHP, pour qu'il s'interprète à son tour, où bien dois-je fais appel à une fonction qui traitera l'alternative et la restituera dores et déjà traitée ?

    J'espère m'être fait compris, et je vous en remercie d'avance !

  2. #2
    Membre Expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Par défaut
    salut,

    une piste à suivre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
    $a = 7;
     
    $pseudocode = '[IF $a > 3] Plus grand [ELSE] Plus petit [ENDIF]';
     
    $reg = '/\[IF ([^\]]+)\]([^\[]+)\[ELSE\]([^\[]+)\[ENDIF\]/';
     
    $replace = 'if ($1) {echo "$2";} else {echo "$3";}';
     
    $code = preg_replace($reg, $replace, $pseudocode);
     
    eval($code);

  3. #3
    Membre confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 99
    Par défaut
    J'ai pensé à l'eval()... mais je n'ai pas testé, va savoir pourquoi. Je viens d'ailleurs tout juste de voir ta réponse, et je vais de ce pas faire mes tests

  4. #4
    Membre confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 99
    Par défaut
    Alors, je confirme que dans l'absolu, ce code fonctionne à merveille et corrige même un point essentiel dans mon preg_replace que j'avais écrit.

    Seulement, voilà le hic lorsque je veux l'intégrer dans ma classe. Dès que je fais l'eval, j'ai une erreur de ce type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Parse error: parse error in C:\wamp\www\_dev\_cms-0.0.1o\classes\CMSTemplate.class.php(68) : eval()'d code on line 1
    J'ai pris soin de retirer tout autre contenu de mon tpl afin de faire le test, mais rien n'y fait.

    J'ai l'objet $this->output, qui est ma chaine. Là, je fais le preg_replace avec le pattern donné. Et donc, je tente de lui dire que $this->output = eval($this->output); presque tout logiquement (selon moi).

    Qu'est-ce qui pourrait causer cette erreur ? Et qu'est-ce que je suis supposé faire face à cela ?

  5. #5
    Membre Expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Par défaut
    Un "parse error" est une erreur du parser php.
    Il s'agit essentiellement d'erreurs de frappe : parenthèses non appareillées, point-virgule manquant, etc...
    Bref, à toi de trouver la coquille.
    Quand ce sera un syntax error ou autre du style, nous pourrons t'aider.


  6. #6
    Membre confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 99
    Par défaut
    Le hic, c'est que en réalité, je récupère donc par exemple ceci:

    $this->output = "Du blabla et du blabli accompagné d'un [IF]...[ENDIF] et encore du blabla";

    Et je réalise le traitement donné plus haut. Au moment de l'eval($this->output), voilà l'erreur.

    J'ai tenté de mettre le preg_replace dans $code et de faire eval($code), mais même erreur. Je ne vois donc pas trop où est le soucis [du moins, comment le régler]

  7. #7
    Membre Expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Par défaut
    Je vois le problème.
    A vue de nez, je jouerais bien avec l'option e des fonctions preg pour voir ce qu'on peut en tirer.
    Mais pas tout de suite, il faut à peu près beau et c'est l'heure de l'apéro.

  8. #8
    Membre confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 99
    Par défaut
    Je peux toujours jouer tout seul, après tout... [même si c'est dans 1h, vu la vaisselle et le chien qui m'attend :p]

  9. #9
    Membre confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 99
    Par défaut
    Bon, voilà à peine que je peux tester (du à la refonte du PC )

    Voici donc ce que j'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Parse error: parse error in C:\wamp\www\_dev\_cms-0.0.1o\classes\CMSTemplate.class.php(63) : regexp code on line 1
     
    Fatal error: preg_replace() [<a href='function.preg-replace'>function.preg-replace</a>]: Failed evaluating code: if (a &gt; 3) {echo &quot; HOURRA &quot;;} else {echo &quot; HOUPPA &quot;;} in C:\wamp\www\_dev\_cms-0.0.1o\classes\CMSTemplate.class.php on line 63
    Encore un Parser Error, et puis alors une Fatal Error.

    Concernant les RegEx, j'ai une question un peu newbie, :

    - Quelle est la différence entre écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $reg = '/\[IF ([^\]]+)\]([^\[]+)\[ELSE\]([^\[]+)\[ENDIF\]/';
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->output = preg_replace('#\[START (.+?)\](.+?)\[END (.+?)\]#si','',$this->output);
    Je ne parle pas du pattern en lui même, mais bien du fait de mettre des slashs ou des dièses,

    Edit: je me suis répondu à moi-même, en testant. C'est donc le modifier, et on peut le choisir en gros. Enfin, plus d'infos peut se faire

  10. #10
    Membre confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 99
    Par défaut
    Bonsoir,

    Je n'ai toujours pas résolu mon problème (même si je l'ai mis de côté un peu, depuis...). Personne n'aurait d'indications ou de possibles solutions à ce dernier ?

    Merci bien

    Edit: J'entrevois le bout ! J'ai réussi, via un exemple trouvé sur le net, à bidouillé un truc potentiellement dans le vent de ce que je voulais. Je fignole tout ce bazar (ça ressemble vraiment à du bazar et très bizarre) et je vous poste le code correspondant, évidemment !

  11. #11
    Membre confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 99
    Par défaut
    Voici donc le code obtenu pour la classe.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->output = preg_replace('#\[IF (.+?)\](.+?)\[ELSE\](.+?)\[ENDIF\]#sie','$this->evalueCond($1,$2,$3)',$this->output);
    La méthode evalueCond:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function evalueCond($cond,$if,$else)
    		{
    			if($cond) { return $if; } else { return $else; }
    		}
    Concernant le template,:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a vaut 5: [IF 5 > 3] HOURRA [ELSE] HOUPPA [ENDIF]
    J'obtiens donc le résultat escompté, néanmoins avec ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Notice: Use of undefined constant HOURRA - assumed 'HOURRA' in C:\wamp\www\_dev\_cms-0.0.1o\classes\CMSTemplate.class.php(59) : regexp code on line 1
    Bon, c'est tout de même problématique pour la suite..., mais dans l'absolu, j'ai enfin réussi à faire ce que je souhaitais.

  12. #12
    Membre confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 99
    Par défaut
    D'ailleurs, dès que je mets dans le template ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a vaut 5: [IF 5 > 3] Plus grand [ELSE] Petit [ENDIF]
    Là, j'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Parse error: parse error in C:\wamp\www\_dev\_cms-0.0.1o\classes\CMSTemplate.class.php(59) : regexp code on line 1
     
    Fatal error: preg_replace() [<a href='function.preg-replace'>function.preg-replace</a>]: Failed evaluating code: $this-&gt;evalueCond(5 &gt; 3, Plus g , Petit ) in C:\wamp\www\_dev\_cms-0.0.1o\classes\CMSTemplate.class.php on line 59
    Je deviens fou !

  13. #13
    Membre confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 99
    Par défaut
    Toujours sur ce problème...

    Bon, j'ai dépatouillé un peu mes faux semblant de conneries, et je suis repartis sur ce que l'on m'avait indiqué [eval()], et sur mes dernières modifications...

    ... donc, j'en suis à ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->output = preg_replace('#\[IF (.+?)\](.+?)\[ELSE\](.+?)\[ENDIF\]#si',$this->evalueCond('$1','$2','$3'),$this->output);
    Et donc, la méthode evalueCond():
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function evalueCond($cond,$if,$else)
    		{
    			if($cond) { $return="a"; } else { $return="b"; }
     
        		return $return; 
    		}
    Seulement, et c'est logique, j'obtiens toujours le même résultat. Il prend mon premier paramètre comme une chaine de caractères, et c'est du à mes quotes dans le preg_replace. Mais comment éviter cela ? :-/

    *Désespère, *

  14. #14
    Membre confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2009
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 99
    Par défaut
    J'ai trouvé ! [J'en rajoute deux parce que c'est bien plus que ça : ]

    Alors, voici comment j'ai procédé:

    Classe Template
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    // IF / ELSE
     
    			$pattern = '/\[IF ([^\]]+)\]([^\[]+)\[ELSE\]([^\[]+)\[ENDIF\]/';
     
    			$replace = 'if ($1) {echo "$2";} else {echo "$3";}';
     
    			preg_match_all($pattern, $this->output, $matches);
     
     
    			foreach ($matches[0] as $key => $match)
    			{
    				$code = preg_replace($pattern, $replace, $match);
    				$codes[] = $this->evalueCond($code);
    			}
     
    			$this->output = str_replace($matches[0],$codes,$this->output);
    Méthode evalueCond()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function evalueCond($code)
    		{
    			ob_start();
    			  eval($code);
    			  $code = ob_get_contents();
    			ob_end_clean();
     
        		return $code;
    		}
    Et dans le template,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <br /><br />
    IF 5 > 3: [IF 5 > 3] Plus grand [ELSE] Plus petit [ENDIF]
    <br /><br />
    IF 1 > 3: [IF 1 > 3] Plus grand [ELSE] Plus petit [ENDIF]
    <br /><br />
    IF 1 < 3: [IF 1 < 3] Plus petit [ELSE] Plus grand [ENDIF]
    <br /><br />
    IF 1 == {number}: [IF 1 == {number}] Egal [ELSE] Different [ENDIF]
    <br /><br />
    Ce qui nous retourne bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    IF 5 > 3: Plus grand
     
    IF 1 > 3: Plus petit
     
    IF 1 < 3: Plus petit
     
    IF 1 == 1: Egal
    Notes: {number} étant assigné à 1 !

    Alors, je suis parti sur un principe similaire mais tout différent, toutefois !

    Je récupère tout d'abord toutes les occurrences de mon preg_match (all). Je traite chacune de celle-ci indépendamment en invoquant une méthode qui permet de ne pas afficher le résultat de mon eval() grâce à un tampon de sortie.

    Par la suite, je fais un simple remplacement du tableau de mes occurrences par un tableau des eval.

    Simple comme bonjour, mais wahouuuu !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [RegEx] preg_replace remplacement précis
    Par guillaume40 dans le forum Langage
    Réponses: 11
    Dernier message: 21/12/2009, 14h54
  2. [RegEx] preg_replace() remplacement partiel.
    Par Jarode01 dans le forum Langage
    Réponses: 7
    Dernier message: 09/12/2009, 09h34
  3. [RegEx] Preg_replace remplacer plusieurs fois une variable
    Par C45T0R dans le forum Langage
    Réponses: 2
    Dernier message: 24/10/2008, 14h39
  4. Equivalent preg_replace de PHP
    Par V_R46 dans le forum C++
    Réponses: 4
    Dernier message: 13/12/2006, 19h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo