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

  1. #21
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    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).

  2. #22
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 857
    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 857
    Points : 6 555
    Points
    6 555
    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.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

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

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Donc pour "A(?=B)(?=C)D" :
    Le marcheur s’arrête sur A et regarde s'il y a B puis il regarde s'il y C, c'est ça ? (donc recherche les chaines "AB" et "AC" ?)
    Puis une fois les chaines trouvés se déplace à D.
    ... donc si je suis mon raisonnement, la chaine "ABACD" devrait matcher... ce qui n'est pas le cas : où est mon problème de réflexion ?

  4. #24
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 857
    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 857
    Points : 6 555
    Points
    6 555
    Par défaut
    Non, A(?=B)(?=C)D échouera toujours quelque soit la chaîne. Car là tu dis qu'immédiatement aprés A il y a B, C et D à la même position (or au max il ne peut y avoir qu'un seul de ces caractères).

    Et pour être précis, arrivé au premier lookahead, le "marcheur" ne s'arrête pas sur A, il vient juste de passer A et se trouve à ses pieds le prochain caractère ou la fin de la chaîne.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

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

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    C'est bon je crois que j'ai compris en testant le regex "A(?=.*B)(?=.*C)DE"


    Le marcheur veut tester la chaine "ZZZZADEZZZCZZZZB" :
    1- Le marcheur avance jusqu’à arriver sur un "A" puis s'arrête.
    2- Il regarde si sur la chaine restante ("DEZZZCZZZZB"), il trouve ".*B".
    3- Ensuite, il regarde si sur la chaine restante ("DEZZZCZZZZB"... toujours la même), il trouve ".*C".
    4- Il redémarre en avançant au caractère suivant et teste "D" sur la chaine "DEZZZCZZZZB".
    5- Il passe au caractère suivant et teste "E" sur la chaine "EZZZCZZZZB".

    C'est bien le bon raisonnement ?

  6. #26
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 857
    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 857
    Points : 6 555
    Points
    6 555
    Par défaut
    Oui là c'est correct.

    Maintenant, merci de répondre à mes questions.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  7. #27
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    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).

  8. #28
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 681
    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 681
    Points : 5 221
    Points
    5 221
    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.

  9. #29
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 857
    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 857
    Points : 6 555
    Points
    6 555
    Par défaut
    Une solution qui gère le chevauchement:
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    function items_overlap(ref, items) {
        let masks = [ref];
     
        for (const item of items) {
            masks = masks.reduce((c, mask) => [...c, ...build_masks(mask, item)], []);
            if (!masks.length) return true;
        }
        return false;
    }
     
    function build_masks(ref, item) {
        let mask, masks = [];
        let chunks = ref.split(item);
        const last_index = chunks.length - 1;
     
        for (let i=0; i<last_index; i++) {
            mask = '';
     
            for (let j=0; j<last_index; j++) {
                mask += `${chunks[j]}${i === j ? "\u{001e}" : item}`; 
            }
     
            mask += chunks[last_index];
            masks.push(mask);
        }
        return masks; 
    }
    Le principe est de splitter une référence avec un des items de l'entrée utilisateur, puis à partir des morceaux de produire des versions masquées de cette référence, exemple avec la référence AIA-123AI et l'item AI: j'obtiens les masques _A-123AI et AIA-123_.

    Si aucun de ces deux masques ne contient l'item suivant, c'est soit qu'il n'est pas dans la référence, soit qu'il se chevauche avec le précédent.

    Test:
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    const refs = [
        'AIA-421UM', 'IAI-674LV', 'AIA-905LU', 'IAI-158DL', 'IAI-569ZK', 'IAI-571IW', 'LAI-955IA', 'AIA-774UI', 'IAI-877QK',
        'IAI-423DF', 'AIA-531NO', 'IAI-589KR', 'IAI-272CI', 'IAI-203ZO', 'IAI-886NO', 'AIA-935CN', 'IAI-431WG', 'AIA-875ZG',
        'IAI-149QK', 'IAN-358AI', 'AIA-575OH', 'IAI-008XU', 'IAI-014LM', 'AIA-032VS', 'IAI-128DV', 'AIG-916IA', 'IAI-589XY',
        'IAI-534IK', 'AIA-496AN', 'NAI-754IA', 'AIA-343UM', 'IAI-844QQ', 'AIA-853DM', 'AIA-608VU', 'AIA-431NN', 'AIA-027NS',
        'IAI-097IC', 'AIA-934WJ', 'AIA-537XC', 'IAI-321IF', 'IAI-401QZ', 'AIA-213VC', 'AIA-150XD', 'AIA-892OG', 'IAI-541SH',
        'AIA-687WO', 'IAI-260ZC', 'AIA-192DH', 'AIA-371GA', 'IAR-826AI', 'AIA-732HZ', 'AIA-354TP', 'AIA-945DZ', 'NAI-746IA',
        'AIA-058WR', 'AIA-810VH', 'VIA-637AI', 'IAI-277EP', 'IAI-794KR', 'AIA-769MG', 'AIA-973XC', 'AIA-488ZK', 'AIA-394WQ',
        'AIA-530GO', 'AIA-096CI', 'AIA-832FF', 'AIA-083DS', 'IAI-320QA', 'IAI-947NO', 'AIA-960ZY', 'IAI-085AD', 'AIA-918UD',
        'AIA-760II', 'IAI-699TN', 'AIA-133EI', 'IAI-750YP', 'AIA-146PS', 'IAI-166IR', 'AIA-654PO', 'IAI-405PZ', 'IAI-483YI',
        'IAI-960WO', 'AIA-273IO', 'AIA-398WC', 'AIA-885KP', 'AIJ-780IA', 'IAI-853WC', 'AIA-192MI', 'KAI-139IA', 'AIA-435ZV',
        'AIA-302HV', 'AIA-276PC', 'IAI-016FK', 'AIA-270SL', 'IAI-014PF', 'IAI-590WS', 'AIA-820QC', 'AIA-818DJ', 'IAI-641KA',
        'AIA-947QB', 'AIA-991LU', 'IAI-201FL', 'AIA-180KL', 'AIA-805JL', 'AIA-781PE', 'IAI-217YR', 'IAI-488AZ'
    ];
     
    const usr_input = ['AI', 'IA']; //['8', 'D']; //['A', 'A', 'A'];
     
    let result = refs.filter((ref) => !items_overlap(ref, usr_input));
     
    console.log(result);
    //[ 'LAI-955IA',
    //  'IAN-358AI',
    //  'AIG-916IA',
    //  'NAI-754IA',
    //  'IAR-826AI',
    //  'NAI-746IA',
    //  'VIA-637AI',
    //  'AIJ-780IA',
    //  'KAI-139IA' ]
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

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

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Merci pour vos réponses, je pense qu'on peu fermer le sujet

    Pour la gestion de chevauchement, je pense aussi qu'on peut le faire une boucle .remplace sur chaque mots clefs : si la référence a toujours la même longueur après un .replace, c'est qu'elle ne contient pas le mot clef et est donc à filtrer.

  11. #31
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 857
    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 857
    Points : 6 555
    Points
    6 555
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    Pour la gestion de chevauchement, je pense aussi qu'on peut le faire une boucle .remplace sur chaque mots clefs : si la référence a toujours la même longueur après un .replace, c'est qu'elle ne contient pas le mot clef et est donc à filtrer.
    Malheureusement ça ne marchera pas pour 2 raisons:
    1. tu risques de créer des sous-chaînes qui n'étaient pas là avant:
      Code texte : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      référence: ABC-123DE
      mots-clefs: B et AC
       
      remplacement de B => AC-123DE (ok)
      remplacement de AC => -123DE (pas ok)
    2. c'est dépendant de l'ordre de remplacement des mots-clefs:
      Code texte : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      référence: ABC-123AS
      mots-clefs: AB et A
       
      ordre: AB, A
      remplacement de AB => C-123AS (ok)
      remplacement de A => C-123S (ok)
       
      ordre: A, AB
      remplacement de A => BC-123AS (ok)
      remplacement de AB => BC-123AS (pas ok)


    C'est pour ces raisons que dans le code que je propose je génère pour chaque mots clef plusieurs références temporaires:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ABC-123AS   =A>   _BC-123AS   =AB>   introuvable
                      ABC-123_S          _C-123_S (il en reste un, ABC-123AS est un résultat pour A, AB)
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  12. #32
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 821
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 821
    Points : 979
    Points
    979
    Par défaut
    Effectivement, tu as raison

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

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