Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1538 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  Regex et prise de tête !

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Regex et prise de tête !

n°2104542
inspecteur​mota
Posté le 03-10-2011 à 22:56:08  profilanswer
 

Bonjour  
 
J'utilise l'expression suivante dans la class de mon moteur de recherche pour afficher  les 15 mots précédents et suivants le mot clé ($cles) tappé par mes visiteurs :
 
preg_match_all(sprintf('`(\b(?:[^\s]+\s){0,15}%s(?:\s[^\s]+){0,15}\b)`i', $cles), html_entity_decode(strip_tags($row[7])), $matches, PREG_SET_ORDER);
$tab[$compteur][7]= preg_replace('#'.$cles.'#i', '<span style="background:#FF3">'.$cles.'</span>', $matches[0][0]);
 
Mon problème est que lorsque mes visiteurs tappent un mot qui est inclus dans un mot de ma BDD (exemple : ils tappent 'voiture' et dans la base j'ai 'voitures'), je n'ai aucun résultat à l'affichage ... De même si mes visiteurs tappent ''voiture' et que dans ma base le mot est suivi d'une virgule ou d'une parenthèse ou que n'importe quel caractère entoure le mot sans espace.
 
Avez-vous des idées pour corriger mon problème ?


Message édité par inspecteurmota le 04-10-2011 à 11:38:10
mood
Publicité
Posté le 03-10-2011 à 22:56:08  profilanswer
 

n°2104591
inspecteur​mota
Posté le 04-10-2011 à 11:42:07  profilanswer
 

En fait j'ai changé mon regex par celui là :
 
$masque = ('/  \b (.{0,75}?) \b \s*? \b ( [\S]* '.$cles.' [\S]* ) \b \s*? \b ((.?[^'.$cles.'?].?).{0,75})  \b /ix');
preg_match_all($masque, html_entity_decode(strip_tags($row[7])), $matches, PREG_SET_ORDER);
$tab[$compteur][7]= preg_replace('#'.$cles.'#i', '<span style="background:#FF3">'.$cles.'</span>', $matches[0][0]);
 
Du coup il attrape les 75 caractères précédents et suivant le mot clé mais ça déconne toujours si le mot est suivi d'un point et d'un saut de ligne (forcément vu l'utilisation du . dans le regex).
 
Qqun a-t-il une idée ?

n°2104831
CyberDenix
Posté le 05-10-2011 à 10:07:47  profilanswer
 

Ta regexp ne m'inspire pas trop, mais je remarque :
1] des espaces inutiles
2] des crochets inutiles autour du \s* et des \b et des ? qu'on se demande à quoi ils servent
3] qu'en fin de ton premier $cles, tu n'offres pas la possibilité de caractères additionnels avec un .*


---------------
Directeur Technique (CTO)
n°2104836
CyberDenix
Posté le 05-10-2011 à 10:19:05  profilanswer
 

Essaye un truc du genre :
 
$regex = '/(.+)('.$searchedWord.')(.+)/Usi';
 
Sinon si c'est juste un highlight que tu veux faire, un simple strtr suffit :
 
$highlightedString = strtr($string, array($searchedWord => '<span class=highlight>'.$searchedWord.'</span>'));
 
A noter que les deux exemples acceptent des tableaux, si tu as besoin d'effectuer des remplacements multiples...


---------------
Directeur Technique (CTO)
n°2104849
inspecteur​mota
Posté le 05-10-2011 à 11:47:07  profilanswer
 

Merci de ta réponse
J'ai testé ton regex mais ça ne fonctionne absolument pas d'autant que le nombre de caractères/mots à afficher n'y apparait pas
1/ les espaces sont inutiles mais ça me permet juste de mieux lire la regex
2/ pour les crochets je vois pas trop de quoi tu parles, il n'y en a pas autour du \s* ni des \b
3/ la regex accepte bien les caractères précédents ou suivants le mot recherché même sans .*
Quant au highlight le mien fonctionne bien aussi (il est indépendant de l'opération avec le regex et s'éxécute après)
 
En fait mon regex fonctionne dans 90% des cas sauf quand il y a un saut de ligne dans le coin

n°2104926
CyberDenix
Posté le 05-10-2011 à 16:42:22  profilanswer
 

Et le \s*? ... Il te sert à quoi exactement ?
 
Parce que ? C'est pour dire de 0 à 1, or comme tu as mis une étoile devant, ça sert à rien.
 
0 ou 1 fois un truc répété de 0 à N fois, ça revient à mettre une restriction
De Max(0x0, 0x1) à Max(0xN, 1xN)
De Max(0, 0) à Max(0, N)
De 0 à N
 
Donc la condition précédente du *
 
Je t'assure que ta regex est faussement compliquée pour ton problème...
 
Au passage, tes espaces ne comptent pas pour du beurre, ils sont évalués !


---------------
Directeur Technique (CTO)
n°2104930
CyberDenix
Posté le 05-10-2011 à 16:49:56  profilanswer
 

Ton problème vient de ta clause de négation. Le motif dans les crochets n'est pas un mot, mais un caractère unique, ayant pour valeur une des lettres constituant $cles
 
Donc si ta chaine de caractère jouant le role de texte présente le mot cles suivit d'un caractère constituant $cles, la regexp ne matche pas (elle ne matche que pour les autres caractères.


---------------
Directeur Technique (CTO)
n°2105054
Volkhen
Posté le 06-10-2011 à 11:41:47  profilanswer
 

CyberDenix a écrit :

Et le \s*? ... Il te sert à quoi exactement ?


A faire un pattern qui n'est pas gourmand.
Bon, dans ce cas il est inutile, mais par exemple un pattern /.*?plop/ appliqué à la chaîne "Lorem ipsum plop dolor sit amet plop" s'arrêtera au premier plop alors que /.*plop/ ne s'arrêtera qu'au dernier.


---------------
Main/Alt1/Alt2/Alt3
n°2105147
CyberDenix
Posté le 06-10-2011 à 19:39:50  profilanswer
 

Donc en fait le U rend toute l'expression greedy et le ? le ferait au cas par cas ?


---------------
Directeur Technique (CTO)
n°2105259
Volkhen
Posté le 07-10-2011 à 15:33:53  profilanswer
 

En gros : si l'expression est greedy (cas par défaut) le ? donne un comportement ungreedy à * et +. Par contre, si l'expression est ungreedy (modifieur U utilisé donc), le ? redonne un comportement greedy à * et +.


---------------
Main/Alt1/Alt2/Alt3
mood
Publicité
Posté le 07-10-2011 à 15:33:53  profilanswer
 

n°2105295
CyberDenix
Posté le 07-10-2011 à 19:24:47  profilanswer
 

Ouais je voulais dire ungreedy. Bon à savoir ! :)


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

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  Regex et prise de tête !

 

Sujets relatifs
Oracle + .Net : casse non prise en charge pour le nom d'interrogationsupprimer marge supérieure en tête
Empecher prise de focusPivotTable + OLAP + Hiérarchie = Casse-tête chinois
Casse-tête Script sauvegarde serverEclipse Tomcat / modification de servlet non prise en compte
[PHP] gd, détecter si une photo a été prise en portraitWORD VB Comment supprimer des liaisons dans l'en-tête?
Problème de syntaxe. Mettre 2 classes pour une pagePrise en charge date complete script de réservation
Plus de sujets relatifs à : Regex et prise de tête !


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR