MarvinLeRouge Posté 13 Mai 2006 Posté 13 Mai 2006 Salut, Je cherche, dans une chaîne de caractère, à remlacer systématiquement toute sous-chaîne encadrée par des crochets par le contenu de la case de même index dans un tableau. Exemple : $remplace = array ("A" => "salut", "B" => "machin");$chaine_depart = "[A] à toi, [b], ça va bien ?"; La chaîne résultat devrait être salut à toi, machin, ça va bien ? En fait, c'est l'utilisation du crochet comme repérage dans l'expression (comme symbole de séparation) qui me pose problème. Merci
smile Posté 13 Mai 2006 Posté 13 Mai 2006 (modifié) $chaine_depart = "[A] à toi, [b], ça va bien ?";$in= array ( '/(\[A\])/', '/(\[b\])/' ); $out = array ( 'salut', 'machin');$chaine_finale=preg_replace($in, $out, $chaine_depart); Dans ce goût là ? Modifié 13 Mai 2006 par smile
MarvinLeRouge Posté 13 Mai 2006 Auteur Posté 13 Mai 2006 (modifié) Dans ce goût là, oui. Il faudrait que la chaine de caractères entre crochets serve d'indice pour le tableau de remplacement : on remplace $X entre caractères crochets (quel que soit $X) par $tableau [$X]. Je ne sais pas si on peut faire ça directement par une expression, où s'il faut trouver un moyen de récupérer toutes les chaines entre crochets avec leurs coordonnées pour après les traiter dans une boucle. NB : Et il faut faire attention au fait de s'arrêter à chaque fois dès le premier crochet fermant (afin de ne pas prendre par exemple 2 mots entre crochets plus ceux qui les séparent), ce que je ne sais pas exprimer en RegExp. Modifié 13 Mai 2006 par MarvinLeRouge
TheRec Posté 14 Mai 2006 Posté 14 Mai 2006 Bonsoir...enfin bonjour C'est là que les backreferences sont très utiles avec les expressions régulières : $chaine_depart = "[A] a toi, [b], ca va bien ?";function val_remplace($matches) { $remplace = array ("A" => "salut", "B" => "machin"); // Remplace false par la valeur qui doit remplacer les balises ne se trouvant pas dans ton tableau return array_key_exists($matches[1],$remplace) ? $remplace[$matches[1]] : false;}$chaine_finale=preg_replace_callback('/\[([a-z]+)\]/i', "val_remplace", $chaine_depart); J'ai utilisé preg_replace_callback car il n'est pas possible d'utiliser une backreference (\\1 ou même \${1}) comme clé d'un tableau directement (avec preg_replace)... on touche au limites de l'interprétation des variables dans une chaîne de caractères...bref, tant mieux, cela permet de réaliser un test supplémentaire sur ce qui est trouvé La classe de caractères [a-z0-9] ne permettant pas le caractères espace, les expression entre cochets de plus d'un mots ne seront pas remplacées... bien entendu à toi de définir une classe de caractères qui te conviendra (par exemple autoriser les sous-tirets, tirets, ...) P.S. Dans le code ci-dessus, [ b ] nest pas remplacé, car les clés de tableaux sont sensibles à la casse...il est tout à fait possible de faire un strtoupper lorsquon veut rechercher la clé dans le tableau et se dire que toutes les clés du tableaux doivent être en majuscules...par exemple)
MarvinLeRouge Posté 14 Mai 2006 Auteur Posté 14 Mai 2006 (modifié) Bonsoir ... enfin bonsoir Merci beaucoup pour votre aide. J'ai réussi à atteindre mon but : je n'ai pas pu utiliser la fonction de callback indiquée parce qu'en l'occurence on est dans un objet et ça semble poser un pb, mais ce n'est pas grave. J'ai simplement trouvé un masque suffisament tolérant pour mes noms de variables (j'ai pris ([a-z0-9\-\_]+)) et j'ai même fait ma petite fonction récursive pour faire les remplacements dans des tableaux à n dimensions. Modifié 14 Mai 2006 par MarvinLeRouge
TheRec Posté 14 Mai 2006 Posté 14 Mai 2006 Merci beaucoup pour votre aide. J'ai réussi à atteindre mon but : je n'ai pas pu utiliser la fonction de callback indiquée parce qu'en l'occurence on est dans un objet et ça semble poser un pb, mais ce n'est pas grave. <{POST_SNAPBACK}> Tu peux préciser un peux plus le problème (un exemple)...parce que si c'est un objet qui est le subject de la fonction preg_replace ou preg_replace_callback ce n'est pas un problème... à condition que la propriété de l'objet que tu souhaites traîter soit de type chaîne de caractères (string). Merci d'avance.
MarvinLeRouge Posté 14 Mai 2006 Auteur Posté 14 Mai 2006 On est dans un objet, qui est instancié, la chaîne à traiter est un paramètre passé à une méthode de l'objet (mais pas une proriété de l'objet), et le tableau contenant les remplacement est lui une propriété de l'objet. (Oui un peu tordu je suis d'accord) Si on indique comme fonction de callback une méthode de l'objet, ça ne semble pas déclencher quoi que ce soit (pas d'erreur non plus d'ailleurs). Et si la fonction est externe à l'objet, ça complique le passage de paramètres. J'ai donc opté pour un appel à preg_match_all, et une boucle de traitement sur les résultats fournis.
TheRec Posté 15 Mai 2006 Posté 15 Mai 2006 Si j'ai bien compris, ton cas le code donnerait ceci avec un callback: <?phpclass Sample { var $remplace = array ("A" => "salut", "B" => "machin"); function SampleMethod($chaine_depart) { return preg_replace_callback('/\[([a-z]+)\]/i', array(&$this, '_remplace'), $chaine_depart); } function _remplace($matches) { return array_key_exists($matches[1],$this->remplace) ? $this->remplace[$matches[1]] : false; }}$sampleInstance = new Sample();echo $sampleInstance->SampleMethod("[A] à toi, [B], ça va bien ?");?> C'est un usage intéressant du type callback, pour appeler la méthode d'une classe on utilise cette syntaxe : array(&$obj, 'user_function') Donc lorsque la méthode doit être appelée en callback à l'intérieur de la class, il suffit d'utiliser &$this (cela représente l'instance de l'objet par référence...je ne t'apprend rien je pense ) et le tour est joué.
MarvinLeRouge Posté 15 Mai 2006 Auteur Posté 15 Mai 2006 Arf c'est vrai j'avais déjà lu ça quelque part, mais j'avais oublié cette syntaxe. Merci
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant