IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Regex pour moteur de recherche [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 16
    Points : 12
    Points
    12
    Par défaut Regex pour moteur de recherche
    Bonjour à tous,

    dans le cadre de la réalisation d'un moteur de recherche, j'essaye de développer un script php qui me permettrait de récupèrer le mot recherché et ceux qui l'entoure afin d'avoir un petit aperçu du contexte dans lequel le mot est employé.
    J'ai donc pensé aux expressions rationnelles. Totalement débutant dans ce domaine, j'ai lu pas mal de tuto et pour l'instant j'en suis qu'a l'élaboration du masque. Je suis arrivé a développer un truc qui fonctionne plus ou moins bien.

    J'aimerais avoir vos avis, savoir comment l'améliorer ou le corriger.
    Je vais décortiquer le code et exposer ce que j'attends de chaque parties.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #(\w+?|\s|\S){0,6}?(for?)(\w+?|\s|\S){0,10}#i
    Le but est de pouvoir sélectionner une portion de phrase contenant le mot recherché, "for" dans l'exemple.

    Cette portion est sensée récupérer les mots, espace ou sans espace, s'ils existent avant le mot recherché avec pour quantité de 0 à 6.
    Problème, la quantification ne fonctionne pas au dela de 6.

    Tous mots composé du mot recherché "for"

    Tous mots, espace, sans espace après le mot recherché avec quantité maximum 10.
    Probleme au dessu de 10, certaines occurences du mot recherché ne sont plus sélectionnées.De même l'ajout d'une condition ? ne selectionne plus rien.

    casse insensible

    Pouvez vous me donner un coup de main ?? car la je galère un peu

    J'ai une solution alternative a base de substr, strpos et autre, mais j'aimerais vraiment voir si il est possible de faire ça en regex.

    Merci d'avance !!!!!

  2. #2
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Un truc à adapter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <?php
     
    $myString = "un deux  trois quatre   cinq six MonMotEstIci apres";
    $pattern = '/(.*)\b([^\bm]*mot.*?)\b(.*)/i';
     
    if ( preg_match($pattern, $myString, $matches) ) {
        $wordsBefore = split(' ', trim($matches[1]));
        $mySearch = $matches[2];
        $wordsAfter = split(' ', trim($matches[3]) );
     
        print "Mot trouvé = $mySearch";
        print "<hr/>";
        foreach($wordsBefore as $myWord) if (trim($myWord)) print "<li>Mot avant = ". trim($myWord);
        print "<hr/>";
        foreach($wordsAfter as $myWord)  if (trim($myWord)) print "<li>Mot après = ". trim($myWord);
    }
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  3. #3
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Bonjour!

    Voilà encore un sujet très intéressant!
    Je me demande si il serait possible de réaliser la même chose avec une requête SQL ?
    Avez-vous une idée de la manière de procéder ?
    De retour parmis vous après 10 ans!!

  4. #4
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    salut jml94,

    merci pour ta réponse.

    Tout d'abord pourrais-tu m'éclairer sur la signification de :
    est-ce que ça veut dire aucun debut ou fin de mot ?
    et le m sert à quoi ?

    j'ai testé le script sur une chaine plus longue, et il me prend la dernière occurrence trouvée.
    J'aimerais trouver toutes les occurrences.
    Je pense donc à preg_match_all qui permet de séparer le mot rechercher de ce qu'il y a avant et apres.
    Comment peux-t-on adapter le code pour preg_match_all ? car la j'ai des resultats identiques, seul la derniere occurrence est trouvée.

    Allez, encore un peu d'aide s'il te plait !!!!!!!!!

  5. #5
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Citation Envoyé par flo974 Voir le message
    salut jml94,

    merci pour ta réponse.

    Tout d'abord pourrais-tu m'éclairer sur la signification de :
    est-ce que ça veut dire aucun debut ou fin de mot ?
    et le m sert à quoi ?

    j'ai testé le script sur une chaine plus longue, et il me prend la dernière occurrence trouvée.
    J'aimerais trouver toutes les occurrences.
    Je pense donc à preg_match_all qui permet de séparer le mot rechercher de ce qu'il y a avant et apres.
    Comment peux-t-on adapter le code pour preg_match_all ? car la j'ai des resultats identiques, seul la derniere occurrence est trouvée.

    Allez, encore un peu d'aide s'il te plait !!!!!!!!!
    C'est pour éviter le classique .* que je n'aime pas trop
    Nous voulons donc tous les caractères sauf une fin de mot ( le \b ) ou un m, qui est tout simplement la première lettre du mot recherché. Mais tu pourrais le faire sauter : la regex en perdrais peut-être un au niveau performances mais serait un peu plus générique. C'est ton choix.

    Il est normal que cela chope la dernière occurrence, c'est du au premier .* de l'expression. Si tu veux attraper la première, je pense que cette variante devrait le faire (je l'aère un peu avec l'option x, sinon elle risque d'être imbuvable) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $pattern = '/^ (.*?) \b ( [^\bm]* mot [^\b]* ) \b (.*) $/xi';
    Pour tout attraper, preg_match_all s'impose effectivement. A compléter.

    Et quand nous aurons trouvé la regex parfaite, il faudra ensuite essayer de lui coller un groupement atomique sur le mot recherché pour augmenter les perfs.
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  6. #6
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    salut

    quelle réactivité !
    encore merci de te pencher sur mon problème.

    ta dernière regex ne fonctionne pas chez moi.
    Sinon j'ai opté pour l'utilisation d'un preg_match_all.
    Le but étant de trouver toutes les occurrences du mot recherché et de separer avec preg_match_all, les mots avant, le mot trouvé, et les mots apres, et ce pour toutes les occurrences.
    J'ai essayé plein de combinaisons différents à partir de tes exemple mais rien à faire et je me perds un peu dans le code.

    J'ai repris à partir du debut :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $pattern = '/(.*?)(tour?)([^tour?]*)/i';
    mais c'est pas encore ça....

  7. #7
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Citation Envoyé par flo974 Voir le message
    ta dernière regex ne fonctionne pas chez moi.
    J'avais fait ça à main levée sans tester. Il semblerait que PCRE n'aime pas cette négation de classe [^\b]

    J'ai donc remplacé ce test en considérant qu'il fallait éviter les blancs :

    Pour avoir le premier mot
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <?php
    $myString = "un deux  trois quatre unMotAvant  cinq six MonMotEstIci apres";
    $pattern = '/^ (.*?) \b ( [\S]* mot [\S]* ) \b (.*) $/ix';
     
    if ( preg_match($pattern, $myString, $matches) ) {
        $wordsBefore = split(' ', trim($matches[1]));
        $mySearch = $matches[2];
        $wordsAfter = split(' ', trim($matches[3]) );
     
        print "Mot trouvé = $mySearch";
        print "<hr/>";
        foreach($wordsBefore as $myWord) if (trim($myWord)) print "<li>Mot avant = ". trim($myWord);
        print "<hr/>";
        foreach($wordsAfter as $myWord)  if (trim($myWord)) print "<li>Mot après = ". trim($myWord);
    }
    Pour avoir le dernier mot (ça j'aime bien ! ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <?php
    $myString = "un deux  trois quatre unMotAvant  cinq six MonMotEstIci apres";
    $pattern = '/^ (.*) \b ( [\S]* mot [\S]* ) \b (.*) $/ix';
     
    if ( preg_match($pattern, $myString, $matches) ) {
        $wordsBefore = split(' ', trim($matches[1]));
        $mySearch = $matches[2];
        $wordsAfter = split(' ', trim($matches[3]) );
     
        print "Mot trouvé = $mySearch";
        print "<hr/>";
        foreach($wordsBefore as $myWord) if (trim($myWord)) print "<li>Mot avant = ". trim($myWord);
        print "<hr/>";
        foreach($wordsAfter as $myWord)  if (trim($myWord)) print "<li>Mot après = ". trim($myWord);
    }
    Je reste à l'écoute pour voir ce que peux donner preg_match_all
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  8. #8
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Hello,

    je pense être proche du saint graaaaaaaaaal !
    notamment grâce à toi jml94

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /  \b(.{0,100}?) \b \b ( [\S]* mot [\S]* ) \b \b ((.?[^mot?].?){0,100})  \b /ix
    utilisé avec un preg_match_all, cette regex permet de trouver toutes les occurrences du mot avec au maximum 100 caractères avant et idem apres le mot.

    jml94 si tu vois des erreurs ou si t'as des idées de perfectionnement... comme se passer de la parenthèse imbriquée sur les mots apres, ne te gènes pas !

  9. #9
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Citation Envoyé par flo974 Voir le message
    jml94 si tu vois des erreurs ou si t'as des idées de perfectionnement... comme se passer de la parenthèse imbriquée sur les mots apres, ne te gènes pas !
    C'est vrai que ça peut influer sur les perfs, aussi tu peux opter pour une parenthèse non capturante (?: ). C'est plus performant, mais un peu moins lisible...
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  10. #10
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Autre modif rapide : des espaces entre les séparateurs de mots pour permettre plus d'espaces

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /  \b(.{0,100}?) \b \s*? \b ( [\S]* mot [\S]* ) \b s*? \b ((.?[^mot?].?){0,100})  \b /ix
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  11. #11
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Merci, ça fonctionne bien !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Structure table pour moteur de recherche
    Par sunshine33 dans le forum Requêtes
    Réponses: 0
    Dernier message: 04/02/2008, 14h32
  2. Dictionnaire sémantique pour moteur de recherche?
    Par Glavio dans le forum SQL Procédural
    Réponses: 0
    Dernier message: 20/07/2007, 11h36
  3. Probleme vba pour moteur de recherche ACCESS
    Par sylvaindenisbe dans le forum Modélisation
    Réponses: 1
    Dernier message: 10/05/2007, 14h30
  4. Algorithme d'indexation pour moteur de recherche
    Par caspertn dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 24/04/2006, 16h57
  5. Problème requete pour moteur de recherche
    Par vincedjs dans le forum Requêtes
    Réponses: 48
    Dernier message: 15/03/2006, 14h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo