8797 sujets

Développement web côté serveur, CMS

Bonjour,

Aujourd'hui je me pose une colle.

J'ai un texte comme celui-ci :


Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<a href="#">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</a>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.


Et je veux mettre une balise <span> uniquement là (en noir)

Lorem ipsum dolor sit amet, [#black]consectetur[/#] adipiscing elit.
<a href="#">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</a>
Lorem ipsum dolor sit amet, [#black]consectetur[/#] adipiscing elit.


D'où mon problème : rechercher un mot qui ne serait pas compris dans un lien.
J'ai essayé plusieur solutions dont les assertions (voir ici )
Mais cela ne marche que s'il n'y a pas d'autre mot dans le lien (c'était trop beau).

J'en appelle maintenant au grand gourou... car même en bidouillant je ne vois pas de solution pourtant tout est possible avec les expressions rationnelles mais comment ?

Un grand merci d'avance à tous pour vos idées
Modifié par masseuro (29 Apr 2009 - 17:09)
Administrateur
Idée
- Remplacer toutes les occurrences de <a href="#">...</a> par {{1}}, {{2}} et les conserver en mémoire
- Remplacer les mots restants (qui ne seront plus ceux compris dans des liens)
- Remplacer les occurrences initiales à leurs positions d'origine
Merci,

c'est en effet une solution.
Je vais remplacer tous les liens par un texte bizarre en les sauvegardant dans une pile.
faire tout mes remplacement.
puis remettre les liens ensuite...

Si quelqu'un a mieux (on sait jamais !) je suis toujours preneur.
En attendant je passe ça en résolu.
Salut,

j'étais parti sur ça :
<?php
$contenu = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<a href="#">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</a>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.';

// Fonctions de callback
function black($matches)
{
	return '<strong>'.$matches[0].'</strong>';
}

function noblack($matches)
{
	$chaine = str_replace ( '<strong>', '', $matches[0] );
	$chaine = str_replace ( '</strong>', '', $chaine );
	return $chaine;
}

$mot = 'consectetur';
$regex = '#'.$mot.'#';
$resultat1 = preg_replace_callback($regex, "black", $contenu);
$regex = '#<a(.*)(<strong>'.$mot.'</strong>)(.*)</a>#';
$resultat2 = preg_replace_callback($regex, "noblack", $resultat1);
echo '<p>'.$resultat2.'</p>';
?>
Mais je ne sais pas si c'est plus rapide ou pas...
L'idée n'est pas mauvaise non plus mais vu qu'au final je mettais un lien (<a>) autour du mot recherché ça n'aurais pas marché.

Mais grâce à dew ça marche !
Pour info le but était de mettre des liens sur des mots qui ont une définition dans un article de façon automatique. Je suis assez content du résultat. Le processus est quasi instantanée pour une base de 300 mots
Voici ce que j'ai fait, (c'est sur wordpress)


function insert_term_in_post($content){
		global $wpdb;
		global $lientab;
		$lientab = array();
		$terms = $wpdb->get_results("SELECT tID,term FROM ".$wpdb->prefix . "gloss_terms");
		$content=preg_replace_callback("(<a [^>]*>.*</a>)","callback_lien_push",$content);
		foreach($terms as $term){
			$content = preg_replace("#\b(".$term->term.")\b#i","<a class='lexique' href='#'>$1</a>",$content);
		}
		$content=str_replace("[[lien]]",array_shift($lientab),$content);
  return $content;
}

function callback_lien_push($matches){
	global $lientab;	
	$lientab[] = $matches[0];	
	return "[[lien]]";
}


Merci..
Salut,

A priori cette expression suffit :


$mot    = 'test';
$string = 'test <a href="#">lien test tester lien</a> tester test';

echo preg_replace( '`\b(' . $mot . ')\b(?![^<]*</a>)`', '<span>$1</span>', $string  );
Yees !

c'est ça ! +1kiwiz

ça marche , enfin presque Smiley fache ( je suis chiant hein ? Smiley langue )

ça ne marche pas dans ce cas :

$string = 'test <a href="#">lien test <strong>tester</strong> lien</a> tester test';


je vais chercher dans cette voie
Si on n'a pas toutes les données du problème aussi. Smiley langue

Essaie avec ça, ça devrait faire l'affaire :

echo preg_replace( '`\b(' . $mot . ')\b((?!.*</a>)|(.*<a.*>))`U', '<span>$1</span>$2', $string );

Modifié par Agylus (30 Apr 2009 - 10:48)
le résultat est un peu bizarre....

Malgré le U il me sélectionne le début du lien (testé ici)

j'ai d'un coté
test <a href="#">  
et de l'autre
test
Heu, aucun problème de mon côté. Et puis ça ne m'étonnerait pas que leur script ait des bugs hein.
Agylus a écrit :
echo preg_replace( '`\b(' . $mot . ')\b((?!.*</a>)|(.*<a.*>))`U', '<span>$1</span>$2', $string );
Ouh Pinaise ! C'était pourtant simple ! Smiley biggol Smiley langue
Mince alors, rien à faire sur plusieurs testeurs ainsi qu'en php directement ça ne marche pas.

à chaque fois mon début de lien se fait remplacer...

c'est pas grave...

En tout cas merci beaucoup à toi Ô grand gourou Agylus des PCRE Smiley prie
masseuro a écrit :
à chaque fois mon début de lien se fait remplacer...

Quelle est la chaine que tu testes exactement ?
Et quel résultat ça te donne ?
Pour info Agylus mon teste ce fait avec


<p>Bienvenue dans WordPress. Ceci est votre premier Kermès <a href="http://www.google.fr">caduc article.</a> Modifiez-le ou supprimer-le, puis <a href="http://www.google.fr">caduc</a> lancez-vous ! caduc</p>


qui devient


<p>Bienvenue dans WordPress. Ceci est votre premier <strong>Kermès</strong>caduc article.</a> Modifiez-le ou supprimer-le, puis <a href="http://www.google.fr">caduc</a> lancez-vous ! caduc</p>


Je remplace le "Kermès"

Comme tu vois le résultat est assez bizarre.

au cas où, le code :

	$terms = $wpdb->get_results("SELECT tID,term FROM ".$wpdb->prefix . "gloss_terms");
		foreach($terms as $term){
			$content = preg_replace( '`\b(' . $term->term . ')\b((?!.*</a>)|(.*<a.*>))`U', "<strong>$1</strong>", $content  );
		}

  return $content;