Re: Circonscrire un eregi_replace ?
Le 01/10/2007 10:20, paul a écrit :
>
> j'ai un module de recherche sur un site. Et sur la page de résultats, je
> surligne le résultat. OK ça marche.
>
> $Contenu = eregi_replace($quoi, "<span class=\"highlight\">\\0</span>",
> $Contenu);
>
> Oui mais, le seul souci c'est que ça me casse le code à l'intérieur des
> liens interactifs puisque ça ajoute le span class. Du style :
> <a href="http://www.<span class="highlight">trucmuche</span>.com">mon
> lien</a>
>
> Comment dire $Contenu = eregi_replace sauf là où c'est encadré par <a
> href et le > suivant ?...
Le plus simple (et le plus sûr) me semble être d'utiliser un analyseur
syntaxique de HTML qui te construit un arbre, et tu n'as plus qu'à faire
le remplacement dans les feuilles avant de générer le résultat. Avec des
expressions rationnelles tu ne peux faire que du bricolage.
Essayons tout de même de bricoler. Je suppose que $quoi contient un
mot, avec donc des lettres le plus souvent, mais pas de signes de
ponctuation et surtout pas d'espaces. Pour éviter le problème que tu
signales, tu peux vérifier avec une « assertion arrière » que le mot
est précédé d'un espace ou du caractère « > » et rien d'autre :
(?<=\s|>)
Par la même occasion tu peux aussi vérifier qu'il se termine à une
frontière de mot :
\b
Cela donnera donc :
$contenu = preg_replace("/?<=\s|>)$quoi\b/",
"<span class='highlight'>$0</span>", $contenu);
Note que l'on ne peut pas à ma connaissance utiliser d'assertion arrière
allant chercher le « a href » car elle ne serait pas de longueur fixe.
Une autre méthode consisterait à rechercher toutes les chaînes comprises
entre « > » et « < » et à effectuer le remplacement que tu souhaites
dans chacune de ces chaînes. Par exemple :
function ma_fonction($matches) {
return preg_replace("/$quoi/", "<span class='highlight'>$0</span>",
$matches[0]);
}
$contenu = preg_replace_callback("/>.*</sU", "ma_fonction", $contenu);
|