JeuWeb - Crée ton jeu par navigateur

Version complète : Encore une regex...
Vous consultez actuellement la version basse qualité d’un document. Voir la version complète avec le bon formatage.
Pages : 1 2
Bonjour

encore un petit problème de regex, et je ne comprends pas du tout pourquoi cela ne marche pas alors qu'il me semble que cela devrait le faire plutôt pas mal...



$text = '[p]<ok>[/p]';

$search = Array ( '0' => '#\[p\](.*)\[/p\]#isU');
$replace = Array ( '0' => htmlentities('$1') );

echo preg_replace($search, $replace, $text,-1,$count);

// affiche ceci:

<ok>

et comme debugage, le preg_replace semble détecter la chaine mais ne la remplace pas ($count)



$count=0;
$text = '[p]<ok>[/p]';

$search = Array ( '0' => '#\[p\](.*)\[/p\]#isU');
$replace = Array ( '0' => htmlentities('$1') );

echo preg_replace($search, $replace, $text,-1,$count);
echo ' $count = ' . $count;

// affiche ceci:

<ok> $count = 1

merci de m'avoir lu, je sais que les regex c'est pénible pour tout le monde...

un coup de pouce?
Salut,

raté, j'adore les regex, car je trouve le mécanisme très puissant :p

preg_replace remplace bien $search par $replace dans ta chaine $text, et $count reçoit bien le nombre de remplacements effectués.
Ta chaine d'entrée '#\[p\](.*)\[/p\]#isU' est cherchée, et trouvée. [p]<ok>[/p] est donc remplacé par htmlentities('$1').
Or, htmlentities est une fonction, non une chaine de caractères, donc elle est exécutée dès la ligne 5. $replace est donc un tableau qui à l'index 0 associe le résultat de htmlentities('$1'), qui doit être $1.
Donc, preg_replace reçoit:

preg_replace('#\[p\](.*)\[/p\]#isU', '$1', '[p]<ok>[/p]',-1,$count)

Et elle s'exécute bel et bien.
Si tu souhaites appliquer htmlentities à ce que la regex capture dans ses parenthèses, il te faut utiliser preg_replace_callback.

Code PHP :
<?php
$count
=0;
$text = '[p]<ok/>[/p]';

$search = Array ( '0' => '#\[p\](.*)\[/p\]#isU');

echo
preg_replace_callback($search,
function (
$p_matches)
{

//var_dump($p_matches);
//$p_matches = array (size=2)
// 0 => string '[p]<ok>[/p]' (length=11)
// 1 => string '<ok>' (length=4)

return htmlentities($p_matches[1]);
}
,
$text,-1,$count);
echo
' $count = ' . $count;

// affiche ceci:
// &lt;ok&gt; $count = 1

?>
Pour comprendre comment $p_matches fonctionne, fais quelques tests avec des chaînes plus complexes et avec des balises [p] imbriquées.
Je comprends pas ce que tu veux faire. Elle fonctionne très bien ta regex, tu demandes à PHP d'aller te remplacer le contenu de ce qu'il y a entre les balises [p] et [\p] par... le même contenu.

Si tu veux juste remplacer les balises [p] de ton code par leur équivalent html, suffit de modifier un peu ton replace:

Code :
<?php
$text = '[p]<ok>[/p]';

$search  = Array ( '#\[p\](.*)\[/p\]#isU');
$replace = Array ( '<p>$1</p>' );

echo preg_replace($search, $replace, $text,-1,$count);
?>

mais bon, si tu veux uniquement faire du remplacement de balisage, utiliser un preg_replace est un peu too much.

Un simple str_replace suffirait.

Code :
<?php
$text = '[p]<ok>[/p]';


$search  = Array ( '[p]', '[/p]');
$replace = Array ( '<p>', '<\p>' );

echo str_replace($search, $replace, $text);
?>
Sauf que str_replace va remplacer [p]Balise non fermée par <p>Balise non fermée et bonjour les injections GUI \o/
Bon, avec <div> au lieu de <p>, ce serait encore pire...

Je pense que ce qu'il cherche à faire, c'est échapper les caractères HTML qui se trouvent uniquement entre les balises [p][/p], mais je me trompe peut-être.
php dispose d'un parser bbcode, tu réinventes la roue la Smile mais libre à toi
+1 pour niahoo

Il existe une foullitude d'implémentation de BBcode sur la toile. Tu n'as qu'à choisir.
Je parle de l'extension officielle :

http://php.net/manual/fr/book.bbcode.php
Oui je sais, j'avais compris. L'extension officielle en fait partie.
(12-08-2013, 11:25 AM)Xenos a écrit : [ -> ]raté, j'adore les regex, car je trouve le mécanisme très puissant :p

Smile , oui heureusement qu'il y a des codeurs qui aiment les regex Smile

Merci de ton aide, je ne suis pas certain d'avoir compris la nécessité d'un callback, mais ça fonctionne à merveille, merci !!!

(12-08-2013, 11:37 AM)Xenos a écrit : [ -> ]Je pense que ce qu'il cherche à faire, c'est échapper les caractères HTML qui se trouvent uniquement entre les balises [p][/p], mais je me trompe peut-être.

oui voilà...

(12-08-2013, 11:46 AM)niahoo a écrit : [ -> ]php dispose d'un parser bbcode, tu réinventes la roue la Smile mais libre à toi

(12-08-2013, 11:54 AM)Arnadus a écrit : [ -> ]Il existe une foullitude d'implémentation de BBcode sur la toile. Tu n'as qu'à choisir.

oui je sais bien, mais mon parseur de bbcode doit traiter des bbcodes très spéciaux, genre bbcode pour afficher un rapport, ou bien une coordonnée sur la carte, et d'autres bbcodes très atypiques...

en tout cas merci, cela fonctionne à merveille avec preg_replace_callback
Le callback est nécessaire. preg_replace ne fait qu'un remplacement littéral: la chaîne de caractères trouvées sera remplacée par la chaîne de caractères $replace, aux $1..$N près.
Dans ton cas, tu aimerais passer la chaîne trouvée à la fonction htmlentities, ce qui n'est pas possible en utilisant une chaîne de caractères $replace dans preg_replace, d'où la callback.

Si htmlentities avait pris, comme paramètre, un tableau $p_matches, la callback aurait pu être directement la fonction htmlentities. Mais ce n'est pas le cas, d'où la nécessité de passer par une callback intermédiaire, aka, une fonction perso (anonyme ici).
Pages : 1 2