tisha_carpenter
samedi 22 mars 2008 à 01:01
CITATION(cdpdf @ vendredi 21 mars 2008 à 07:49)

Je ne comprend pas pourquoi avec la fonction suivante, les accents des mots sont considérés comme inexistants.
Tu es dans un environnement configuré en autre chose que ISO-8859-(1 ou 15). PHP récupère les facilités du système d'exploitation sous le nom de locale et la fonction PHP setlocale() peut changer cette configuration le temps de l'exécution du script si la "locale" voulue est accessible par le système d'exploitation (et au moins PHP 4.3). Toutes les fonctions string de PHP sont soumises à cette configuration. Il y a toujours moyen de contourner ou de s'adapter si un changement de configuration est impossible et que
setlocale() ne donne aucun résultat. Mais à la base, tu es en présence d'un problème de configuration. La ligne suivante devrait te dire dans quel encodage ton système est:
CODE
<?php
echo setlocale(LC_CTYPE,null);
?>
CITATION(cdpdf @ vendredi 21 mars 2008 à 07:49)

De plus, j'ai dans ma base de donnée des mots avec des espaces genre "webmaster hub" ou encore des mots aves des tirets genre "tisha-carpenter" et parfois avec des apostrophes "l'apéro"tout ces mots ne ressortent pas avec la requête
Ce que j'avais posté ici concernait le mot et non pas la phrase. La classe \b est à proscrire car \b est très très gourmant et refusera tout caractère non-mot à l'intérieur de l'énumération, \b doit être utilisé uniquement pour délimiter un mot car il donne un gain en temps d'exécution (cf.: test rapidement l'échec). Par contre dans la fonction
ajouter_liens, la ligne:
CODE
$regex='#<('.$balises.')[\s>].+?</\1>|<[^>]+>|\b('.$mots.')\b#si';
peut-être remplacer par:
CODE
$regex='#<('.$balises.')[\s>].+?</\1>|<[^>]+>|(?<=\W)('.$mots.')(?=\W)#si';
Et ça devrait fonctionner aussi pour la phrase comme pour le mot sur un tri par longueur comme dans ton code.
Surtout pour array('la très belle'=>'tisha carpenter');

CITATION(cdpdf @ vendredi 21 mars 2008 à 07:49)

* je suis obligé de tester tous les mots de ma base de donnée (plus de 2000) ça fait mal à ma base à chaque fois.
Je vois pas comment soulager ta base, sauf par une mise en cache de la requête. Car il devient impossible de savoir si un espace doit être conservé ou éliminé, à moins de faire aussi toutes les combinaisons de 2 mots par proximité, ce qui serait un tout autre genre de bestiaux.
CITATION(cdpdf @ vendredi 21 mars 2008 à 07:49)

* obligé de rajouter des tirets pour tous les mots composés
Ne devrait plus être nécessaire après la correction regex proposée un peu plus haut. Dans un bon encodage de caractère, bien entendu. Ta base est encodé en quoi? Tes documents HTML sont encodés en quoi?
CITATION(cdpdf @ vendredi 21 mars 2008 à 07:49)

* je ne sais pas évité de faire des changement dans les balises (un point très important)
OK. Je vais essayer de faire ma prof

aucune garantie de satisfaction.
- Le méta-caractère | permet d'énumérer des possibilités sous la forme de OU logique. L'ordre d'énumération est important puisqu'il doit aller du plus important au moins important.
- J'utilise ce | pour énumérer 3 hypothèses
- Hypothèse des balises exclues <('.$balises.')[\s>].+?</\1>
Revient à isoler de la balise ouvrante à la balise fermante inclusivement selon l'énumération contenu dans $balises. Par exemple, le HTML "<h1>une texte de titre</h1>" sera complètement capturer en un bloc parce que h1 fait partie de $balises. - Hypothèse des attributs des autres balises <[^>]+>
Permet d'isoler tous les attributs des autres balises car le mot pourrait être présent dans ces attributs. - Hypothèse des phrases/mots recherchés (?<=\W)('.$mots.')(?=\W)
Isolera une phase/mot de l'énumération contenu dans $mots, qui est précédé et suivi par un caractère \W, donc précédé ou suivi par un caractère non-mot tel que défini par locale (ref.: setlocale).
Voilà donc pourquoi $regex='#<('.$balises.')[\s>].+?</\1>|<[^>]+>|(?<=\W)('.$mots.')(?=\W)#si';
Le preg_replace_callback($regex,__FUNCTION__,$html); permet de valider quelle partie de la chaine est isolée, si l'expression régulière est satisfaite avant d'arriver à la seconde parenthèse qui énumère les phases/mots alors la capture numéro 2 sera indéfini... donc aucun changement. Par contre, si la capture de la seconde parenthèse est définie, alors un mot/phrase à remplacer a été trouvé. Le code PHP exécuter par ce callback est:
CODE
// Traitement php de l'appel récursif sur preg_replace_callback
if(isset($html[2])) { // un mot a été trouvé pour remplacement
$mot_texte=$html[0];
$mot_url=strtolower($mot_texte);
if(count($mots_id)) { // S'il y a une relation id=>mot alors transposer
$mot_url=array_search($mot_url,$mots_id,true);
if(!$mot_url) return $html[0]; // Couvrir un échec (peu probable)
$mot_url=strtolower($mot_url);
}
return sprintf($remplacement,rawurlencode($mot_url),$mot_texte);
}
return $html[0]; // Cas où aucun remplacement
Qui est la logique expliquée plus haut

Le tout en parcourant une seule fois le document HTML.
En espérant que mon message t'aidera à progresser vers ton objectif.
Tisha