8791 sujets

Développement web côté serveur, CMS

Salut,

je cherche à ajouter des liens à certains endroits d'une page HTML.
Cependant, je ne veux que ces liens ne soient créés QUE en dehors des balises a, strong, et img.
On pourrait dire, que ces liens ne seraient créés que à l'intérieur des balises P.

Sauf que, évidemment, les balises a, strong ou img sont IMBRIQUÉES dans des balises P!

J'ai essayé:
$pattern = "#" .$terme . " (?!</a>)(?![^<]+>)#si";
$text = preg_replace($pattern, '<a class="definition" rel="#definition_' . $i . '" href="#" >' . $terme . '</a> ', $text);


qui fonctionne en ne rajoutant pas mes liens dans des balises a déjà existantes.

Comment faire pour les balises img et strong?

On peut voir sur cette page:
http://www.starting-block.org/asso/notre-demarche

le terme ECS est recherché
Modifié par LiliwoL (21 Jun 2012 - 17:45)
MErci, c'est très intéressant.

Cependant, ça ne m'aide qu'à moitié.

Cette fonction permet de chosiir si on veut appliquer un preg_replace à l'intérieur des balises ou à l'extérieur.

Moi ce dont j'ai besoin c'est de n'appliquer le preg_replace que à l'intérieur des balises, mais de CERTAINES balises uniquement (P sans descendants, c'est à dire pas un A dans un P, ou un STRONG dans un P)
Comme j'en aurai besoin aussi, j'ai un peu cherché, et voilà ce que je peux te proposer :


$texte = 
  '<h3>bonjour à tous</h3><br>' . "\n" 
. 'bonjour à tous<br>' . "\n" 
. '<a href="">bonjour à tous</a><br>' . "\n" 
. '<b>bonjour à tous</b><br>' . "\n" 
. '<p>bonjour à tous</p>';

function coucou($match)
{
	$return = preg_match('#<(.*?)>#si',$match[0]) ? $match[0] : 'coucou';
	
	return $return;
}

$texte = preg_replace_callback(
			'/(bonjour)|(?:<a .+?>.+?<\/a>)|(?:<h[0-9]{1}>.+?<\/h[0-9]{1}>)/i'
			,'coucou'
			,$texte);

echo $texte;


Ce n'est pas super optimisé, mais en gros, le résultat retourné est le suivant :


<h3>bonjour à tous</h3><br>
coucou à tous<br>
<a href="">bonjour à tous</a><br>
<b>coucou à tous</b><br>
<p>coucou à tous</p><hr>


Et donc, tu auras compris que dans l'expression, je définis les balises refusés (ici <a > et <hX>) dont les mots intérieurs ne seront pas changé comme tu peux le voir sur le résultat
Modifié par kenor (22 Jun 2012 - 19:57)
Il vaut pas mieux définir les éléments à remplacer plutôt que ceux à ne pas remplacer ? En utilisant un objet DOMDocument et en ne sélectionnant que les nœuds enfants de type texte des balises <p>.
Modifié par jb_gfx (22 Jun 2012 - 20:22)
jb_gfx a écrit :
Il vaut pas mieux définir les balises a remplacer plutôt que celle à ne pas remplacer ? En utilisant un objet DOMDocument et en ne sélectionnant que les nœuds enfants de type texte des balises &lt;p&gt;.


XPath power Smiley langue
Après, je ne connais pas l'objectif.

Dans mon cas, c'est juste pour placer du lien, donc à part les <hX> et <a >, le reste faut que ça passe.

DOMXPath, ce n'est pas encore un reflex pour moi Smiley cligne Je ne m'en sers que très rarement.
Merci pour toutes vos réponses.

En effet, quand on cherche à modifier du code HTML, il est sûrement plus intéressant de passer par des fonctions faites pour ça.

Je résumé donc pour ceux que ça pourrait intéresser:

* Solution en PREG_REPLACE (solution de Kenor)
$texte = 
  '<h3>bonjour à tous</h3><br>' . "\n" 
. 'bonjour à tous<br>' . "\n" 
. '<a href="">bonjour à tous</a><br>' . "\n" 
. '<b>bonjour à tous</b><br>' . "\n" 
. '<p>bonjour à tous</p>';

function coucou($match)
{
	$return = preg_match('#<(.*?)>#si',$match[0]) ? $match[0] : 'coucou';
	
	return $return;
}

$texte = preg_replace_callback(
			'/(bonjour)|(?:<a .+?>.+?<\/a>)|(?:<h[0-9]{1}>.+?<\/h[0-9]{1}>)/i'
			,'coucou'
			,$texte);

echo $texte;



* Solution en DOMDOCUMENT + XPATH (faite pour ça)
$texte = "<p>truc<a href='truc.html'>truc</a></p><h1>truc<p>truc</p></h1>";
$dom = new DomDocument();
$dom->loadHTML($texte);
$xpath = new DOMXpath($dom);
$elements = $xpath->query('//p/node()[not(self::*)][contains(.,"texteRecherché")]');
if (!is_null($elements)) {
  foreach ($elements as $element) {
    echo "<br/>[". $element->nodeName. "]" . " " . $element->nodeValue;
  }
}



Le souci avec la méthode XPATH est que la recherche est sensible à la casse!
Après, le peu dont je me suis servis de xpath, le gros soucis c'est qu'il faut que ce soit bien formé. Si le code est un peu trop crados, xpath renvoi n'importe quoi ...
Salut, ou sinon tu peux créer un fichier .php que tu include dans balise P, dans le fichier .php tu aurait une fonction qui va cherche ce que tu veux comme liens (je dis lien parce que le principe est de récuperer le contenue d'une page web par xemple, et d'en sortir la balise que l'on souhaite, le tout dans une boucle, et tu récupérer tout les H3 d'un site dans une div en particulier) voici le code :


	
	function Compteur_Titre_Prod()
{
	//La page qu'on veut utiliser
	$SiteURL = ''; // Le site que tu veux (l'url)
	
	//On initialise cURL
	$ch = curl_init();
	//On lui transmet la variable qui contient l'URL
	curl_setopt($ch, CURLOPT_URL, $SiteURL);
	//On lui demdande de nous retourner la page
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	//On envoie un user-agent pour ne pas être considéré comme un bot malicieux
	curl_setopt($ch, CURLOPT_USERAGENT, ''); // entre les deux '' mettre du texte
	//On exécute notre requête et met le résultat dans une variable
	$resultat = curl_exec($ch);
	//On ferme la connexion cURL
	curl_close($ch);
	
	//On crée un nouveau document DOMDocument
	$SitePage = new DOMDocument();
	//On y charge le contenu qu'on a récupéré avec cURL
	$SitePage->loadHTML($resultat);
	 
$txt = $resultat;
 
preg_match_all('`<h3>(.+?)</h3>`i', $txt, $out);
	foreach($out[0] as $o)
	{
	  echo $o;
	}


}

Modifié par JuseN (02 Jul 2012 - 17:16)