Problème de regex - impossible d'interprêter $1

Petit nouveau ! | 5 Messages

30 juil. 2010, 18:19

Bonjour,

premier message ici pour vous demander de l'aide sur un truc sur lequel je m'arrache les cheveux depuis un moment :D
Je dois parser une chaine de texte.
A certains moments je vais trouver des chaines du type [VAR]pseudo[/VAR].
Ce que je souhaite c'est remplacer cette chaine par la valeur de mon tableau correspondante.

Par exemple j'ai écrit ceci :
private function cleanMessageForFlash($pMessage, $pIdUser){
		$user = array();
		$user['pseudo'] = "Befa";
                $user['prenom'] = "Fabrice";
                $user['code_user'] = "F12345";
                 etc...
		$patterns = array();
		$patterns[0] = '/\[VAR\]([[:alpha:]]*_?[[:alpha:]]*)\[\/VAR\]/i';
		
		$replaces = array();
		$replaces[0] = $user['$1'];
		
		$cleanText = preg_replace($patterns, $replaces, $pMessage);
		return $cleanText;
	}
si dans mon replaces[0] je passe juste $1 il va bien me récupérer pseudo, ou bien code_user, en revanche si j'essaie d'utiliser cette variable $1 comme indice de mon tableau il ne l'interprète plus que comme la chaine de caractère '$1' ...
J'ai essayé en faisant des eval($1) ou en appelant une fonction et en lui passant $1 en paramètre mais toujours sans succès.

Si quelqu'un a une petite idée pour me dépanner je l'en remercie d'avance :)

ViPHP
ViPHP | 5462 Messages

31 juil. 2010, 20:14

hello, il faut grouper le autre élément

[VAR] = $1
pseudo = $2
[/VAR] = $3

au niveau de ton preg_replace tu feras $1nouveau_pseudo$3 :wink:

Petit nouveau ! | 5 Messages

02 août 2010, 11:14

Bonjour,

merci pour cette réponse mais je ne saisis pas bien en quoi cela règlera mon problème.
Je n'ai pas de soucis pour récupérer la valeur qui se trouve entre les balises [VAR] et [/VAR] mon soucis est pour interprêter le contenu de ce que je trouve.

A priori j'ai trouvé une solution qui semblerai fonctionner :
                $variable = '$user->' . "$1" . '';
		$cleanText = preg_replace('/\[VAR\]([[:alpha:]]*_?[[:alpha:]]*)\[\/VAR\]/Ui', $variable, $preText);
		eval( "\$cleanText= \"$cleanText\";" );
En sachant que mon objet $user est défini au dessus.
Je ne trouve pas ça très propre de faire un eval de la totalité mais si je n'ai pas d'autre solution tant pis.

ViPHP
ViPHP | 4039 Messages

02 août 2010, 12:37

C'est pas grave, stealth35 oublie des fois de lire la question jusqu'au bout.

Ceci dit, dans ton cas, je pense que tu devrais pouvoir utiliser preg_replace_callback(), avec une fonction anonyme pour gérer tes remplacements. C'est la solution idéale :wink:.
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Petit nouveau ! | 5 Messages

02 août 2010, 14:14

Bonjour Berzemus et merci pour ta réponse.

J'ai effectivement essayé avec preg_replace_callback et un create_function comme ceci ;

$cleanText = preg_replace_callback('/\[VAR\]([[:alpha:]]*_?[[:alpha:]]*)\[\/VAR\]/Ui', create_function('$x', 'global $user; return $user->$x[1];'), $preText);

Et pourtant cela ne fonctionne pas non plus.
Peut être est ce du au fait que ma fonction est dans une classe (un service AMFPHP pour communiquer entre flash et une BDD pour info), mais même en passant $user en global ça ne fonctionne pas (il me supprime mes occurrences trouvées mais ne met rien à la place).

ViPHP
ViPHP | 4039 Messages

02 août 2010, 14:17

Plutôt de d'utiliser create_function, essaye avec une fonction anonyme (c'est plus propre, et entre-nous, j'ai toujours trouvé create_function bancal).
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Petit nouveau ! | 5 Messages

02 août 2010, 15:09

J'ai bien essayé avec function mais cela me génère une erreur PHP (j'utilise la version 5.2.8 peut être que cela vient de la).

Il faudrait bien faire comme ceci : ?
$cleanText = preg_replace_callback('/\[VAR\]([[:alpha:]]*_?[[:alpha:]]*)\[\/VAR\]/Ui', function($x){ global $user; return $user->$x[1]; }, $preText);

ViPHP
ViPHP | 5462 Messages

02 août 2010, 15:30

bon allé je me rattrape :wink:

t'etais pas loin il faut juste rajouter l'option e et mettre le replace en chaine
$patterns = array();
$patterns[0] = '/\[VAR\]([[:alpha:]]*_?[[:alpha:]]*)\[\/VAR\]/ie';
               
$replaces = array();
$replaces[0] = '$user["$1"]';

Petit nouveau ! | 5 Messages

02 août 2010, 16:09

Bon voila finalement une solution qui me semble assez propre (elle n'est pas de moi c'est un ami qui me l'a soufflée :D)

Je crée d'abord une variable $user à ma classe

Ensuite en faisant ainsi :
$cleanText = preg_replace_callback('/\[VAR\]([[:alpha:]]*_?[[:alpha:]]*)\[\/VAR\]/Ui', array(&$this, 'getValue'), $preText);

et en rajoutant une méthode getValue

private function getValue($x){
	return $this->user->$x[1];
}
ça me semble pas mal comme ça non ?

En tout cas merci pour votre aide :)