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

JavaScript Discussion :

Création d'un regex avancé [RegExp]


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 850
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 850
    Par défaut Création d'un regex avancé
    Bonjour,

    Actuellement, j'ai une liste de référence produit.
    Chaque référence produit est constituée des caractères suivants : lettre en majuscule, chiffres, certains caractères spéciaux (".", "/", "-", "*", "_", "(", ")").
    Les références produit ne contiennent pas d'espace.

    J'ai créé un système de recherche qui affiche la liste de produits associés en fonction de la valeur d'un champs de recherche renseignée par l'utilisateur.
    Bien que les références soient renseignées dans la BDD qu'avec des lettre en majuscule, si l'utilisateur entre des minuscules, la recherche fonctionne quand même.
    Bien que les références soient renseignées dans la BDD sans contenir d'espaces, si l'utilisateur entre des espaces, ceux-ci sont ignorés dans la recherche.
    Le caractère "µ" est remplacé dans la recherche par le caractère "U".

    Par exemple, si on a cette BDD :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    AAA-123US
    AAA-124US
    BBB-124US
    BBB-124AS
    Si l'utilisateur entre dans le champs de recherche "124 µS", ça affiche :
    Voici que le code qui génère le regex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function getProductRegex(reference){
    	//console.log(reference);
    	let newReference = reference.replace('µ', 'U') // remplacement µ par U
    								.toUpperCase() // conversion en majuscule
    				                .split(' ').join(''); // suppression des espaces
    	//console.log(newReference);
     
    	let re = $.ui.autocomplete.escapeRegex(newReference);
     
    	let matcher;
    	matcher = new RegExp(re);	
     
    	return matcher;
    }
    La BDD (Base De Données) est stockée sous forme de variable dans mon script javascript :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var bdd = ["AAA-123US", "AAA-124US", "BBB-124US", "BBB-124AS"];

    Maintenant, j'aimerai améliorer le système pour que la recherche fonctionne par mots clefs séparés par des espace.
    Par exemple si l'utilisateur entre dans le champs de recherche "µS 124 BBB", que ça affiche :
    ... que le regex recherche toutes les chaines de caractères qui contiennent TOUS les mots clef entrés (peu importe l'ordre).

    Comment faire cela ?

    Merci d'avance

  2. #2
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 658
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 658
    Billets dans le blog
    1
    Par défaut
    Tu parles de BDD
    Les données sont dans un table MySQL ?

    Il serait peut être plus intéressant de faire la recherche en utilisant le fulltext ?
    https://www.w3resource.com/mysql/mys...-functions.php
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 850
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 850
    Par défaut
    Non les données sont enregistrées dans une variable locale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var bdd = ["AAA-123US", "AAA-124US", "BBB-124US", "BBB-124AS"];
    ... je vais rajouter cette infos dans mon premier message.

  4. #4
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 658
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 658
    Billets dans le blog
    1
    Par défaut
    Ha ok

    Donc si on rentre des suites de caractères séparés par des espaces il faudra rechercher selon les "mots" ainsi rentrés ?

    Faut il que tous les mots soient présent ou la recherche est elle "ou" ?

    Il suffira de récupérer la chaine de recherche, la splitter et constituer une nouvelle regex avec des pipes ...
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 850
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 850
    Par défaut
    Malheureusement, c'est un "et" que je veux faire. Je pourrais faire autant de passe regex qu'il y a de mots clefs mais on ne peut pas gérer ça directement via un regex ?
    ... et puis faire plusieurs passes, ça ne marche bien pour la gestion des recouvrements (ex: recherche de "AB BC" va matcher la chaine "ABC" alors que ça ne devrait pas).

  6. #6
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 658
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 658
    Billets dans le blog
    1
    Par défaut
    un et OK mais dans l'ordre ?

    du coup tu pourrais faire une reg par mot et ainsi faire un score de match
    ceux qui matche tous les mots ... =100%
    ceux qui matche tous les mots -1 = nbr mots-1 / nbre mots *100 %
    etc ...
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  7. #7
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    En amont, en amont... Oui mais imagine rien qu'un millier de références à entrer!
    Et puis n'oublions pas que la saisie peut être elliptique par rapport aux références. On peut saisir "a" et espérer un résultat comprenant "AAA".

  8. #8
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 984
    Par défaut
    Citation Envoyé par javatwister Voir le message
    En amont, en amont... Oui mais imagine rien qu'un millier de références à entrer!
    Et puis n'oublions pas que la saisie peut être elliptique par rapport aux références. On peut saisir "a" et espérer un résultat comprenant "AAA".
    Un millier, c'est une broutille!

    La génération de l'objet map ne prend que quelques dixièmes de seconde (et encore) et est faite une fois pour toutes: sous nodejs, j'atteint la seconde (génération aléatoire du tableau de références et test avec une entrée utilisateur compris) qu'à partir de 300 000 références!

    Quant au temps de recherche lui-même, il est totalement négligeable, même avec des entrées elliptiques.

    Il faut bien voir que le nombre de clefs de la map est majorée et ne dépassera pas 19252 entrées quelque soit le nombre de références (19252 = 26^3 + 10^3 + 26^2) et quelles sont associées à des Sets de nombres. Donc l'occupation en mémoire ne coutera à quelque chose près pas plus chère que le tableau d'origine. Pour illustrer, passé 10.000 références, le nombre d'entrées de la map devient inférieur à celui du tableau.

    Par contre, le problème de chevauchement des éléments de l'entrée utilisateur reste entier, mais sera plus rapide à régler une fois ce premier filtrage effectué (par exemple pour 1 million de références, j'obtiens ~150 résultats contenant AI et IA).

  9. #9
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    Tu peux tester le bout de code ds une page et voir si ça marche?

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 850
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 850
    Par défaut
    A priori avec cette méthode ça fonctionne (testé avec le moteur de recherche en mode Regex du logiciel Notepad++) : https://stackoverflow.com/questions/...s-in-any-order
    ... par contre, je n'ai pas bien comprise comment fonctionne ce regex.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ^(?=.*US)(?=.*124)(?=.*BBB).*$
    Match bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    BBB-124US
    BBBUS-124
    BBBUSUS-124
    Et ne match pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    AAA-124US
    AAA-123US
    AAA-123US
    BBB-124AS

  11. #11
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    Je ne comprends toujours pas ce que tu fais...

    Je me répète mais tu n'as pas besoin de regexp: l'utilisateur tape 2 ou 3 "mots" clés et tu affiches les données qui contiennent ces mots clés...
    Donc, à peu près rien à coder;

  12. #12
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 984
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    A priori avec cette méthode ça fonctionne (testé avec le moteur de recherche en mode Regex du logiciel Notepad++) : https://stackoverflow.com/questions/...s-in-any-order
    ... par contre, je n'ai pas bien comprise comment fonctionne ce regex.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ^(?=.*US)(?=.*124)(?=.*BBB).*$
    C'est simple cette pattern teste en partant du début de la chaîne (^) pour chaque test avant (?=...) (lookahead) si US, 124 et BBB sont bien présent dans la chaîne. (À noter que .*$ ne sert à rien, on se doute bien que la chaîne va finir un jour).
    Par contre ce qu'elle ne fait pas c'est de résoudre le problème de chevauchement: ^(?=.*AB)(?=.*BA) trouvera ABC-123BA mais aussi ABA-123US.


    Accessoirement, il serait utile de savoir de quoi on parle: quel est le format précis des références? Est-ce qu'il y en a plusieurs qui coexistent? Quelle est la taille de ton tableau de références? Pourquoi sont-elles en dur dans ton javascript, d'où viennent-elles?

  13. #13
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 984
    Par défaut
    En fait je me suis compliqué la vie pour rien, j'étais tellement persuadé que le parcours du tableau allait être lent que j'ai cherché une solution de rechange qui en plus résoudrait le problème de chevauchement, mais en fait il est rapide même avec beaucoup d'éléments et le problème de chevauchement n'est pas résolu dans le cas de saisies élliptiques avec ma méthode. Je vais chercher autre chose.

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 850
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 850
    Par défaut
    J'ai beau lire des tutos sur les lookahead, je n'arrive toujours à comprendre ce que ça fait exactement.

    Si j'ai bien compris le regex suivant cherche "A" suivit de "B" ou "C" puis suivit de D ?
    Je ne comprends pas pourquoi il faut que B et C soit présents obligatoirement et l'ordre n'a pas d'importance.

    C'est quoi la différence avec ça ?

    Au final, gérer les chevauchement n'est peut-être pas si important (d'ailleurs, je viens de tester le logiciel Everything dont je me suis servit comme inspiration et il ne gère pas les chevauchements... je vais faire sans alors).
    ... mais ça peut quand même être intéressant de savoir comment le faire

    Entre une solution à base de indexOf où l'on fait une boucle pour tester chaque mot clef sur la chaine et ce regex, il y a une différence de performance ? (dans mon cas, je n'ai pas énormément de références à gérer mais autant utiliser la meilleure méthode).

  15. #15
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 984
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 984
    Par défaut
    Le lookahead ne consomme pas de caractères contrairement à une classe de caractères ou le point qui consomme un caractère puis avance à la position suivante dans la chaîne. À la fermeture du lookahead on est toujours au même endroit dans la chaîne qu'à son ouverture.
    Si tu veux une analogie, un lookahead, c'est un marcheur qui s'arrête pour regarder au loin avec ses jumelles, il sait ce qu'il l'attend sans pour autant s'y être rendu. Si ce qu'il voit lui plait, il continue, sinon il abandonne.

  16. #16
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    Au final, gérer les chevauchement n'est peut-être pas si important (d'ailleurs, je viens de tester le logiciel Everything dont je me suis servit comme inspiration et il ne gère pas les chevauchements... je vais faire sans alors).
    ... mais ça peut quand même être intéressant de savoir comment le faire

    Entre une solution à base de indexOf où l'on fait une boucle pour tester chaque mot clef sur la chaine et ce regex, il y a une différence de performance ? (dans mon cas, je n'ai pas énormément de références à gérer mais autant utiliser la meilleure méthode).
    Voilà, on y arrive!

    ==> le problème du chevauchement n'en est pas vraiment un: si l'utilisateur est assez intelligent, il ne va pas saisir n'importe quoi étant donné ce qu'il veut obtenir;

    ==> indexOf est toujours plus rapide qu'une regexp;

    ==> une regexp n'a d'intérêt que si le masque peut correspondre à plusieurs chaînes différentes: ici, ce n'est pas le cas.

  17. #17
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 850
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 850
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    quel est le format précis des références?
    Chaque référence produit est constituée des caractères suivants : lettre en majuscule, chiffres, certains caractères spéciaux (".", "/", "-", "*", "_", "(", ")").
    Les références produit ne contiennent pas d'espace.
    Les références produit sont composée des sous-chaines qui ont une signification... d'où l’intérêt de pouvoir faire une recherche par mots clefs.

    Citation Envoyé par CosmoKnacki Voir le message
    Est-ce qu'il y en a plusieurs qui coexistent?
    Non mais on peut avoir "AAA" et "AAAB".

    Citation Envoyé par CosmoKnacki Voir le message
    Quelle est la taille de ton tableau de références?
    500 éléments au max.

    Citation Envoyé par CosmoKnacki Voir le message
    Pourquoi sont-elles en dur dans ton javascript, d'où viennent-elles?
    Elle sont en dur pour éviter d'avoir à gérer un langage coté serveur (ex: PHP)... et accessoirement de pouvoir aussi l’exécuter en mode hors ligne pour faciliter les tests (pas indispensable). C'est site Web basique qui consiste à afficher des informations sur une référence produit sélectionnée avec un moteur de recherche qui intègre un système d’autocomplétion (affiche la liste des produits en fonction des mots clefs renseignés).

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

Discussions similaires

  1. [RegExp] Aide pour la création d'un regex
    Par beegees dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 15/08/2011, 14h11
  2. Erreur 400 : création de barres d'avancement
    Par polo31 dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 28/07/2011, 10h21
  3. Création d'une Regex (TextBox Float)
    Par snakzbenjy dans le forum Silverlight
    Réponses: 2
    Dernier message: 13/04/2011, 20h07
  4. Création du site web Avancé
    Par wkd dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 13/07/2007, 14h30
  5. [RegEx] Probleme de création d'un regex
    Par mathis49 dans le forum Langage
    Réponses: 6
    Dernier message: 15/06/2007, 12h08

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