Remplacements automatiques dans articles HTML

Remplacements automatiques dans articles HTML - PHP - Programmation

Marsh Posté le 21-08-2011 à 21:51:34    

Bonjour,
 
Je m'occupe d'un site internet gérant des articles postés par différents utilisateurs et enregistrés dans une base de données en HTML.
 
J'essaye de mettre au point quelque chose permettant la citation automatique des articles entre eux. Le but est donc de repérer, dans tous mes articles, si l'utilisateur a cité le nom d'un autre article et d'automatiquement transformer ça en lien.
 
Exemple : J'ai un article qui s'appelle "bidule", je veux donc que toutes les occurrences de "bidule" se transforme en <a href="bidule.php">bidule</a>.
 
Jusque là, pas de problème, je peux prendre un truc tout bête du genre
 

Code :
  1. $requete = mysql_query("SELECT * FROM remplacements" );
  2.  while($rep = mysql_fetch_array($requete))
  3.   {
  4.    $contenu = preg_replace("#\\b(".$rep['rep_search']." )\\b#i", "<a href='article.php' >" . $rep['rep_replace'] . "</a>", $contenu);
  5.   }


 
Maintenant, ce code ne va pas fonctionner pour plusieurs raisons :
 
- Vu que l'article est en html, ça n'empêche pas les utilisateurs d'écrire des trucs du genre <a href="bidule.php">un truc</a>, qui seront automatiquement remplacés par <a href="<a href="bidule.php">bidule</a>.php">un truc</a>...
- Si j'ai des des images dont le nom contient bidule, idem.
- Si j'ai des balises title avec bidule, idem.
- Etc.
 
 
Il me faudrait donc une REGEX qui prend tous les cas, sauf lorsque bidule est à l'intérieur d'une balise html quelconque, ou entre un <a></a>.
 
Je suis déjà allé sur plusieurs forum et je n'ai pas réussi à trouver de réponse, je désespère donc...
 
Merci d'avance,
 
7804j


Message édité par 7804j le 21-08-2011 à 21:52:13

---------------
7804j
Reply

Marsh Posté le 21-08-2011 à 21:51:34   

Reply

Marsh Posté le 22-08-2011 à 14:11:12    

Tu cherches à faire des traitements compliqués (condition, boucle...) sur un preg_replace.
 
La fonction qu'il te faut, peut-être, est preg_replace_callback(), qui permet, sur capture du pattern, d'appeler une fonction de traitement. En fin de fonction il faut bien entendu retourner la chaîne de remplacement.
 
http://php.net/manual/fr/function. [...] llback.php
 
Pour ta regexp, n'hésite pas utiliser les modifiers Usi (Ungreedy, multiline et case-insensitive -> je les utilise dans 99,99% de mes regexp), les parenthèses capturantes et leurs remplacements respectifs, les jokers style .+ ou .* , les back-references \1 \2 ...etc.
La combinaison de ces éléments devrait t'aider grandement.


Message édité par CyberDenix le 22-08-2011 à 14:16:49

---------------
Directeur Technique (CTO)
Reply

Marsh Posté le 22-08-2011 à 16:51:41    

Euh...Oui mais tout ça je connais déjà :/
 
Le problème, c'est que dans ce cas précis, j'arrive pas à mettre tout ça en application pour que ça fonctionne :(


---------------
7804j
Reply

Marsh Posté le 22-08-2011 à 18:31:45    

Tu n'as pas bien lu ou bien compris :
Si, à l'aide des parenthèses capturantes, tu captures le contenu de 'un truc', dans ta fonction de callback, tu peux tester si il est vide, et donc déterminer si il faut ou non le remplacer par 'bidule'.
Il te suffit donc de capturer des petits morceaux de ton pattern et de les tester afin de savoir ce que tu vas renvoyer.
 

Code :
  1. $out = preg_replace_callback('`<([^ ]+)([^>]*)>(.*)<([^ ]+)>`Usi', 'myCallbackFunction', $myString);
  2. echo $out;
  3.  
  4. function myCallbackFunction($matches) {
  5.  print_r($matches);
  6.  return $matches[2];
  7. }


 
J'ajoute que tu n'es pas obligé de tout faire dans une seule regexp si ceci te semble trop complexe.  
Capture d'abord le nom de la balise et les attributs, puis redécoupe les attributs, puis trouve le href... etc.
Dans preg_replace(), fonction moins évoluée, le before et le after peuvent néanmoins être des tableaux, ce qui peut s'avérer très utile...  
Dans cette hypothèse, une regexp par type de balise (ouvrante/fermante) me semble adapté.
 
Si tu maîtrises vraiment ce que j'ai dis plus haut, avec la doc php, tu ne devrais avoir aucun mal à réussir.


Message édité par CyberDenix le 22-08-2011 à 19:09:48

---------------
Directeur Technique (CTO)
Reply

Marsh Posté le 24-08-2011 à 10:34:05    

Au lieu de raisonner sur le code HTML brut, on peut aussi envisager de raisonner sur le DOM, comme ça tu pourras très facilement exclure tout ce qui est ancres, images & autres et ne te concentrer que sur ce qui est lisible par l'utilisateur.


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 24-08-2011 à 15:39:55    

Oui, j'y ai pensé, mais un des atouts principaux de cette méthode est d'optimiser de manière spectaculaire le référencement google "à la wiki". Si je rajoute des liens par javascript, ça risque d'être moins bien pris par google :/
 
Enfin bon, j'ai fini par trouver une technique très...barbare mais qui fonctionne ^^'^
 
Merci quand même de votre aide.


---------------
7804j
Reply

Marsh Posté le 24-08-2011 à 15:41:21    

7804j a écrit :

Oui, j'y ai pensé, mais un des atouts principaux de cette méthode est d'optimiser de manière spectaculaire le référencement google "à la wiki". Si je rajoute des liens par javascript, ça risque d'être moins bien pris par google :/
 
Enfin bon, j'ai fini par trouver une technique très...barbare mais qui fonctionne ^^'^
 
Merci quand même de votre aide.


 
Non mais tu le fait côté PHP avec la classe DOMDocument.


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 24-08-2011 à 16:06:11    

Ah, alors désolé, j'ai mal compris.
 
Le problème, dans ce cas, est plutôt lié au fait que je ne maitrise absolument pas ce fonctionnement :/


---------------
7804j
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed