Coloration de mots-clés

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 200 fois - Téléchargée 15 fois

Contenu du snippet

C'est une class qui permet de surligner les résultats d'une recherche.

Elle a la particularité d'être insensible aux accents et majuscules. On peut préciser un degrés de différence entre les mots, pour pallier d'éventuelles fautes de frappes de la part de l'utilisateur, ou mots au pluriels par exemples.

Si cette option ne vous intéresse pas, il suffit de mettre le pourcentage à 1. Cela aura de plus pour effet de ne pas utiliser la fonction levenshtein().

Désormais, si vous entourez une phrase par des guillemets, seule cette phrase sera surlignée.

Source / Exemple :


<?php

function get_microtime(){

	list($tps_usec, $tps_sec) = explode(" ",microtime());
	return ((float)$tps_usec + (float)$tps_sec);

}

$tps_start = get_microtime();

class keywordsHighlight {

	function __construct(){
	
		// Code HTML à placer autour des mots-clés trouvés ("%s" sera remplacé par le mot-clé)
		$this->format = '<strong>%s</strong>';
	
	}
	
	// Fonction de simplification d'une chaine de caractères : elle la met en miniscule et retire tous les accents
	function simple($str){
		
		$str = trim($str);
		$str = strtolower($str);
		$str = strtr($str, "àáâãäåòóôõöøèéêëçìíîïùúûüÿñ", "aaaaaaooooooeeeeciiiiuuuuyn");
		$str = preg_replace("`[^a-z0-9'-]*`", "", $str);
		
		return $str;

	}
	
	function compare($i_rank, $i_keywords, $i_words){

		$min = min($this->words['len'][$i_words], $this->keywords['len'][$i_rank][$i_keywords]);
		$max = max($this->words['len'][$i_words], $this->keywords['len'][$i_rank][$i_keywords]);
		
		// Si le rapport entre les nombres de lettre est trop peu élevé, on passe au mot d'après
		if($min / $max >= $this->percent){
		
			if($this->percent == 1)
			
				$test = ($this->words['simple'][$i_words] === $this->keywords['simple'][$i_rank][$i_keywords]);
			
			else
			
				$test = (1 - levenshtein($this->words['simple'][$i_words], $this->keywords['simple'][$i_rank][$i_keywords]) / $max >= $this->percent);
		
		}
		
		return $test;
	
	}
	
	function keywordsInitialisation($rank, $i_keywords){
	
		$this->keywords['simple'][$rank][$i_keywords] = $this->simple($this->keywords['value'][$rank][$i_keywords]);
		$this->keywords['len'][$rank][$i_keywords] = strlen($this->keywords['value'][$rank][$i_keywords]);
	
	}
	
	function highlight($i_words, $i_words_end = false){
		
		// On surligne un mot tout seul
		if(!$i_words_end)
			$this->words['value'][$i_words] = sprintf($this->format, $this->words['value'][$i_words]);
		
		// Ou une phrase entiere du mots $i_words au mot $i_words_end
		else{
		
			$this->words['value'][$i_words] = str_replace(strstr($this->format, '%s'), '',$this->format).$this->words['value'][$i_words];
			$this->words['value'][$i_words_end] = $this->words['value'][$i_words_end].str_replace('%s', '', strstr($this->format, '%s'));
		
		}
	
	}

	/* 

	keywordsHighlight ($text, $keywordsStr, $percent = .8)
		
		$text : Texte dans lequel on surligne les mots clés
		$keywordsStr : Liste des mots clés à surligner séparés par des espaces
		$percent : Pourcentage de ressemblance entre les mots du texte et les mots clés à surligner (une fois en minuscule et les accents rétirés)
			Par défaut: 0.8 => correspond a peu pres à:
				- aucune lettre de différence pour des mots jusqu'à 4 lettres
				- une lettre de différence pour les mots de plus de 5 lettres
				- deux lettres de différence pour les mots de plus de 12 lettres
			Si ce pourcentage est égal à 1, la fonction levenshtein ne sera pas utilisé. (Après quelques tests, la fonction levenshtein n'a pratiquement aucune incidence sur la rapidité du script)
		
		return: Le texte avec les mots clés surlignés

  • /
function textHighlight($text, $keywordsStr, $percent = .8) { $this->percent = $percent; $text = preg_replace("`[\s]+`", " ", $text); //Supprime les doubles espaces $this->words['value'] = explode(' ', $text); // Récuperation des phrases-clées preg_match_all('`"([^"]+)"`', $keywordsStr, $keywordsSentences); $keywordsSentences = $keywordsSentences[1]; // Récupération des mots-clés $keywordsStr = str_replace($keywordsSentences, "", $keywordsStr); // Retire les phrases clées de la liste de mots clés $keywordsStr = str_replace('"', '', $keywordsStr); // Supprimer les doubles quotes $keywordsStr = preg_replace("`[\s]+`", " ", $keywordsStr); // Place les mots clés dans le tableau $keywords au rank 0 $this->keywords['value'][0] = explode(' ', trim($keywordsStr)); // Place les phrases clées dans le tableau $keywords au rank $i_rank for($i_rank=1; $i_rank<=count($keywordsSentences); $i_rank++){ // Place les mots clés d'une phrase clée $i_rank dans le tableau $keywords['value'][$i_rank] $this->keywords['value'][$i_rank] = explode(' ', trim($keywordsSentences[$i_rank-1])); // initialisation des infos pour chaque keywords de la phrase clée $i_rank $keysentences_count[$i_rank] = count($this->keywords['value'][$i_rank]); for($i_keywords=0; $i_keywords<$keysentences_count[$i_rank]; $i_keywords++) $this->keywordsInitialisation($i_rank, $i_keywords); } $words_count = count($this->words['value']); $rank_count = count($this->keywords['value']); $keywords_count = count($this->keywords['value'][0]); for($i_words=0; $i_words<$words_count; $i_words++){ $this->words['simple'][$i_words] = $this->simple($this->words['value'][$i_words]); $this->words['len'][$i_words] = strlen($this->words['simple'][$i_words]); for($i_rank=0; $i_rank<$rank_count; $i_rank++){ // On explore les mots-clé seuls if($i_rank == 0){ for($i_keywords=0; $i_keywords<$keywords_count; $i_keywords++){ // On initialise les mots clés pour la premiere fois if($i_words == 0){ $this->keywordsInitialisation(0, $i_keywords); } if($this->compare(0, $i_keywords, $i_words)) $this->highlight($i_words); } } // On explore les phrases-clées else{ // Si le mot précédent pouvait etre contenu dans une phrase clées, on regarde si celui-ci peut correspondre à la suite de la phrase if(isset($keysentences_possible[$i_rank])){ if($this->compare($i_rank, $keysentences_possible[$i_rank], $i_words)){ // Si tous les mots ont correspondu à une phrase clée, on surligne if($keysentences_possible[$i_rank]+1 == $keysentences_count[$i_rank]) $this->highlight($i_words - $keysentences_possible[$i_rank], $i_words); // Si ce mot correspond a la suite de la phrase clée, on incrémente else $keysentences_possible[$i_rank] += 1; } // Si le mot ne correspond pas au mot suivant de la phrase clée, on réinitialise la variable else unset($keysentences_possible[$i_rank]); } else{ // Si ce mot est le premier d'une phrase clée if($this->compare($i_rank, 0, $i_words)) $keysentences_possible[$i_rank] = 1; } } } } //print_r($this->keywords); return implode(' ', $this->words['value']); } } // Exemple : $texte = 'Quelle pertinence pour le comparatisme subsémiotique ? Prémisces du comparatisme subsémiotique. On ne saurait assimiler, comme le fait Descartes, le monogénisme métaphysique à un amoralisme, cependant, il conteste la relation entre monogénisme et herméneutique. Comme il est difficile d\'affirmer qu\'il décortique la réalité subsémiotique du comparatisme, il est manifeste qu\'il identifie l\'origine du comparatisme. Par le même raisonnement, on ne saurait écarter de notre réflexion la critique de l\'antipodisme irrationnel par Kant et si d\'une part on accepte l\'hypothèse qu\'il donne alors une signification particulière à une science spéculative comme concept empirique de la connaissance alors même qu\'il désire l\'opposer alors à son cadre social, et si d\'autre part il réfute l\'analyse métaphysique sous un angle rationnel, cela signifie donc qu\'il réfute la réalité rationnelle du comparatisme. On pourrait, pour conclure, mettre en doute Montague dans son analyse idéationnelle du kantisme. C\'est d\'ailleurs pour cela qu\'on ne peut contester la critique de la science générative par Descartes, et premièrement Spinoza donne une signification particulière à l\'origine du comparatisme, deuxièmement il en décortique la réalité primitive sous un angle transcendental. De cela, il découle qu\'il s\'approprie l\'origine du comparatisme. Cependant, il examine l\'origine du comparatisme, et le positivisme phénoménologique ou le positivisme ne suffisent pas à expliquer le positivisme spéculatif en tant qu\'objet transcendental de la connaissance. Premièrement il particularise alors la conception déductive du comparatisme, deuxièmement il réfute l\'origine phénoménologique dans une perspective nietzschéenne contrastée. Il en découle qu\'il s\'approprie l\'expression originelle du comparatisme. C\'est dans une optique qu\'il s\'approprie l\'expression universelle du comparatisme afin de prendre en considération le positivisme rationnel. Cependant, il identifie la relation entre maximalisme et géométrie. On ne saurait pourtant reprocher à Bergson son monogénisme transcendental, pourtant, il est indubitable qu\'il envisage l\'origine du comparatisme. Notons néansmoins qu\'il en rejette la démystification empirique en regard du monogénisme. Ainsi, on ne saurait assimiler, comme le fait Spinoza, le réalisme à un monogénisme minimaliste et le fait qu\'il conteste l\'origine du comparatisme signifie qu\'il en donne une signification selon la réalité rationnelle comme objet déductif de la connaissance. Le comparatisme permet, finalement, de s\'interroger sur un monogénisme de l\'Homme. Pourtant, il est indubitable qu\'il donne une signification particulière à l\'analyse subsémiotique du comparatisme. Il convient de souligner qu\'il en caractérise l\'expression empirique en tant qu\'objet rationnel de la connaissance. D\'une part Leibniz donne pourtant une signification particulière à l\'analyse rationnelle du comparatisme, d\'autre part il en examine l\'analyse existentielle en tant que concept transcendental de la connaissance. On peut reprocher en effet à Montague son réalisme substantialiste. Mais il ne faut pas oublier pour autant qu\'il rejette l\'analyse transcendentale du comparatisme. Néanmoins, il conteste la démystification subsémiotique du comparatisme, et le monogénisme rationnel ou le réalisme post-initiatique ne suffisent pas à expliquer le monogénisme minimaliste en tant que concept existentiel de la connaissance. On ne peut considérer qu\'il systématise alors l\'origine du comparatisme qu\'en admettant qu\'il en spécifie la réalité substantialiste en tant qu\'objet irrationnel de la connaissance alors qu\'il prétend l\'opposer à son cadre social et politique. C\'est dans une optique identique qu\'il spécifie la relation entre finalisme et raison afin de la resituer dans sa dimension sociale et politique. C\'est avec une argumentation identique qu\'on ne saurait assimiler, comme le fait Rousseau, le connexionisme transcendental à un connexionisme rationnel. Nous savons que Kierkegaard spécifie pourtant l\'origine du comparatisme. Or il en systématise la destructuration synthétique dans sa conceptualisation, c\'est pourquoi il rejette l\'analyse synthétique du comparatisme pour l\'opposer à son cadre politique. Il faut cependant contraster ce raisonnement : s\'il se dresse contre la démystification substantialiste du comparatisme, c\'est également parce qu\'il en identifie la réalité originelle en regard du connexionisme ; le comparatisme ne peut, par ce biais, être fondé que sur l\'idée du primitivisme sémiotique. Nous savons qu\'il envisage en effet la démystification synthétique du comparatisme. Or il en caractérise l\'aspect spéculatif en tant qu\'objet spéculatif de la connaissance, c\'est pourquoi il rejette la démystification métaphysique du comparatisme pour l\'opposer à son contexte politique et intellectuel. Pour cela, on peut reprocher à Bergson son primitivisme idéationnel dans le but de le resituer dans toute sa dimension politique et sociale. Contrastons cependant cette affirmation : s\'il décortique la conception post-initiatique du comparatisme, c\'est également parce qu\'il en particularise la destructuration rationnelle comme concept subsémiotique de la connaissance, et le paradoxe du minimalisme illustre l\'idée selon laquelle le minimalisme et le minimalisme ne sont ni plus ni moins qu\'une esthétique irrationnelle synthétique. On ne saurait alors ignorer l\'influence de Spinoza sur l\'esthétique transcendentale, et pourtant, il est indubitable que Spinoza conteste la démystification circonstancielle du comparatisme. Il convient de souligner qu\'il réfute l\'aspect déductif dans une perspective montagovienne contrastée. Le paradoxe du minimalisme illustre, de ce fait, l\'idée selon laquelle le minimalisme substantialiste et le minimalisme subsémiotique ne sont ni plus ni moins qu\'un minimalisme irrationnel synthétique. Néanmoins, il s\'approprie la démystification synthétique du comparatisme et la forme cartésienne du comparatisme est, de ce fait, déterminée par une intuition rationnelle de l\'esthétique transcendentale.'; $keywordsHighlight = new keywordsHighlight(); $keywords = 'Montague "en effet" comparatisme "C\'est dans une optique"'; echo "Les mots clés sont: <strong>$keywords</strong><br /><br />"; echo $keywordsHighlight->textHighlight($texte, $keywords); ?>

A voir également

Ajouter un commentaire

Commentaires

Messages postés
1
Date d'inscription
dimanche 1 octobre 2006
Statut
Membre
Dernière intervention
29 octobre 2008

Le code c'est très intéressant, mais je trouve deux soucis :
- Si on met dans les keywords quelque chose comme « origine » on ne trouve pas dans le texte, même sŽil existe. Mais toutes les occurrences sont de la forme « l'origine » et, comme il ni a pas de espace la fonction qui découpe les paroles prend « l'origine » comme un mot. Peut être il faut d’abord convertir « ' » dans espace pour le texte (mais c’est une norme particulier pour quelques langues, comme le français mais pas pour des autres, comme l’espagnol).

- Je ne suis pas codeur, mais j’ais tracée la fonction et j’ais vis que la comparaison ce fait avec chaque parole du texte contre chaque keyword. Donc s’il y a plusieurs fois un keyword on (re)trouve et compare chaque fois pour y souligner de forme individuelle. Je crois que ce serait plus efficace comparer chaque keyword dans le texte et à chaque occurrence, surligner d’un coup « tous » les occurrences qui existent dans le texte, puis invalider le keyword et continuer avec le keyword suivant.

Pour y mesurer la fonction j’ais ajoutée un timer, $tps_end = get_microtime();, au final du code

echo $keywordsHighlight->textHighlight($texte, $keywords);
$tps_end = get_microtime();

$interval= ($tps_end - $tps_start)* 1000 ;
echo "Temp : ($tps_end - $tps_start) en segundos";
echo "";

echo " Temp : $interval en ms";


Et mois aussi je trouve que ce serait préférable de mettre les keywords dans un tableau (array), ou bien d’accepter un tableau comme paramètre et détecter si la liste de keyword arrive comme chaine, et il faut la découper, o déjà comme tableau.
Messages postés
44
Date d'inscription
jeudi 20 novembre 2003
Statut
Membre
Dernière intervention
28 janvier 2013

Slt MangaII,

si dans la fonction simple(), tu rajoutes en premier la fonction strip_tags():
$str = strip_tags($str);

Je n'ai pas testé, mais ca doit pouvoir le faire.
+++
Messages postés
129
Date d'inscription
dimanche 9 décembre 2001
Statut
Membre
Dernière intervention
12 janvier 2009

Ca ma l'air pas mal du tout !
J'ai l'impression que c'est quand même un peu compliqué pour l'effet recherché ... mais bon !

Je suis confronté à un cas un peu plus compliqué, c'est de colorer des mots clés, dans un texte HTML !
Le soucis c'est qu'il faut garder les balises HTML, détecter les mots clés, rajouter des balises autour, le tout sans perturber le contenu ...

Une idée pour adapter cette source ???

Nico
Messages postés
44
Date d'inscription
jeudi 20 novembre 2003
Statut
Membre
Dernière intervention
28 janvier 2013

OK, donc je viens de la modifier fortement pour prendre en compte les phrases clées, comme suggéré par codefalse (Par contre j'ai tjs pas compris comment tu voulais que je fasse, donc j'ai fais à ma manière!).

Le code est maintenant un peu plus compliqué à comprendre qu'avant, et surement moins optimisé! Dc si vous remarquez des trucs à changer dites le moi!

+++

PS: si vous avez du mal a comprendre la structure du tableau $keywords (et notamment l'arrivée du $i_rank), faites un rapide print_r($this->keywords); !
Messages postés
1293
Date d'inscription
mardi 9 novembre 2004
Statut
Membre
Dernière intervention
21 mai 2015

je rectifie j'avais pas fait gaffe pour le unset($test);

mais bon utiliser un unset est inutile surtout que ta variable est même pas instanciée à ta première itération autant le remplacer par

$test = false;

surtout que rien ne justifie de libérer cette variable, ça serait un objet ça serait utile car gain de place en mémoire mais à la réinitialiser à false suffit... unset c'est bien en abuser ça craint... .. . ;o)

@ tchaOo°
Afficher les 10 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.