Remplacement sélectif, hors ou dans balises html
Posté : 13 févr. 2005, 14:16
J'ai souvent vu des questions concernant le remplacement dans une page html sans toucher à ce qui est encadré par des balises
Exemple: comment remplacer le mot texte dans la chaîne suivante:
Texte 1 < 2 hors balises<div id="texte">suite du texte<a href="http://texte.com">texte hors balise</a></div> texte final'
sans toucher aux id="texte" et autres href="http://texte.com"? (la présence de 1 < 2 n'est pas innocente!)
Ou l'inverse, modifier le contenu des balises html sans toucher au reste.
J'ai essayé de synthétiser ce genre de traitement. Le groupe de fonctions suivant permet de faire, au choix, un remplacement hors balises html ou dans les balises html (flag 1 ou -1).
La fonction split_balise() accepte de travailler avec :
Si vous trouvez des erreurs ou incompatibilités, j'essayerai de les corriger.
Exemple: comment remplacer le mot texte dans la chaîne suivante:
Texte 1 < 2 hors balises<div id="texte">suite du texte<a href="http://texte.com">texte hors balise</a></div> texte final'
sans toucher aux id="texte" et autres href="http://texte.com"? (la présence de 1 < 2 n'est pas innocente!)
Ou l'inverse, modifier le contenu des balises html sans toucher au reste.
J'ai essayé de synthétiser ce genre de traitement. Le groupe de fonctions suivant permet de faire, au choix, un remplacement hors balises html ou dans les balises html (flag 1 ou -1).
La fonction split_balise() accepte de travailler avec :
- str_replace
ereg_replace
eregi_replace
preg_replace
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
FONCTIONS POUR REMPLACEMENT SELECTIF, HORS OU DANS BALISE HTML
pour str_replace ou preg_replace :
string split_balise(mixed pattern, mixed replacement, string subject, string function [, int flag])
pour ereg et eregi :
string split_balise(string pattern, string replacement, string subject, string function [, int flag])
flag [option]: flag = 1: remplacement HORS balises (défaut)
flag INT autre que 1: remplacement DANS balises
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
PREMIERE VERSION (3 fois plus lente)
function mon_rplc($capture1, $capture2, &$de, &$par, $fct, $flag){
return ($flag == 1)
? $fct($de, $par, stripslashes($capture1)).stripslashes($capture2)
: stripslashes($capture1).$fct($de, $par, stripslashes($capture2));
}
function split_balise($de, $par, $txt, $fct, $flag = 1){
$eval_fct = "mon_rplc('\$1', '\$2', \$de, \$par, '$fct', '$flag')";
return preg_replace('#((?:(?!<[/a-z]).)*)([^>]*>|$)#ies', $eval_fct, $txt);
}
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
function mon_rplc_callback($capture){
global $arg;
return ($arg['flag'] == 1)
? $arg['fct']($arg['de'], $arg['par'], $capture[1]).$capture[2]
: $capture[1].$arg['fct']($arg['de'], $arg['par'], $capture[2]);
}
function split_balise($de, $par, $txt, $fct, $flag = 1){
global $arg;
$arg = compact('de', 'par', 'fct', 'flag');
return preg_replace_callback('#((?:(?!<[/a-z]).)*)([^>]*>|$)#si', "mon_rplc_callback", $txt);
}
Pour illustrer son fonctionnement, voici quelques exemples:
$txt = 'Texte 1 < 2 hors balises<div id="texte">suite du texte<a href="http://texte.com">texte hors balise</a></div> texte final';
// exemple 1
// str_replace ou ereg_replace
// cet exemple remplace 'texte' par 'TEXTE' hors balises (option 1)
echo split_balise('texte', 'TEXTE', $txt, 'str_replace', 1);
echo split_balise('#texte#', 'TEXTE', $txt, 'preg_replace', 1);Texte 1 < 2 hors balises<div id="texte">suite du TEXTE<a href="http://texte.com">TEXTE hors balise</a></div> TEXTE final
// exemple 2
// str_replace ou ereg_replace
// cet exemple remplace 'texte' par 'TEXTE' dans les balises (option -1)
echo split_balise('texte', 'TEXTE', $txt, 'str_replace', -1);Texte 1 < 2 hors balises<div id="TEXTE">suite du texte<a href="http://TEXTE.com">texte hors balise</a></div> texte final
// exemple 3
// eregi_replace (insensible à la casse)
// cet exemple remplace 'texte' ou 'Texte' par 'TEXTE' hors balises
echo split_balise('texte', 'TEXTE', $txt, 'eregi_replace', 1);TEXTE 1 < 2 hors balises<div id="texte">suite du TEXTE<a href="http://texte.com">TEXTE hors balise</a></div> TEXTE final
// exemple 4
// str_replace avec des tableaux en argument
// remplace d'abord 'texte' par 'TEXTE' ensuite tous les 'e' par 'Z'
$in = array('texte','e');
$rpl = array('TEXTE','Z');
echo split_balise($in, $rpl, $txt, 'str_replace', 1);TZxtZ 1 < 2 hors balisZs<div id="texte">suitZ du TEXTE<a href="http://texte.com">TEXTE hors balisZ</a></div> TEXTE final
// exemple 5
// preg_replace avec remplacement de références arrières
// remplacement hors balises (option 1)
echo split_balise('#(h)(.+?)(s)#s', '$1ORS$3', $txt, 'preg_replace', 1);Texte 1 < 2 hORSs balises<div id="texte">suite du texte<a href="http://texte.com">texte hORSs balise</a></div> texte final
// exemple 6
// preg_replace avec remplacement de références arrières
// remplacement dans balises (option -1)
echo split_balise('#(id=")(.+?)(")#s', '$1$2_plus_long$3', $txt, 'preg_replace', -1);Voilà, j'espère que cela pourra vous être utile.Texte 1 < 2 hors balises<div id="texte_plus_long">suite du texte<a href="http://texte.com">texte hors balise</a></div> texte final
Si vous trouvez des erreurs ou incompatibilités, j'essayerai de les corriger.