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 :

Compréhension REGEX avant personnalisation [RegExp]


Sujet :

JavaScript

  1. #1
    Membre actif
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 388
    Points : 209
    Points
    209
    Par défaut Compréhension REGEX avant personnalisation
    Bonjour,

    Débutant en matière de REGEX, je souhaiterais comprendre les mécanismes de la REGEX suivante (qui a pour effet de mettre en surbrillance les caractères recherchés dans une chaîne) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var string ="écouteur";
     
    string = string.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(écoute)(?![^<>]*>)(?![^&;]+;)", "gi"),
    "<span style='color:#8F5935;font-weight:bold;'>$1</span>");
    Avec ce code, les caractères “écoute” de la chaîne “écouteur” sont mis en surbrillance.
    J’ai du mal à comprendre la syntaxe de la REGEX (en mode objet si j’ai bien compris). Cette syntaxe avec le mot recherché entre parenthèses, encadré par des patterns elles-mêmes entre parenthèses, est-elle habituelle ? Que fait exactement cette REGEX ? Que donnerait-elle en mode littéral ? Je souhaite y voir clair car mon objectif est de modifier la REGEX pour la rendre insensible aux accents (pour le moment , si je recherche le mot “ecouteur”, la chaîne string n’est pas surlignée à cause de l’accent sur le e ). D’ailleurs, si vous avez une piste sur le sujet, je suis preneur. Merci d’avance de votre aide.

  2. #2
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    Aaah la gestion des accents avec les Regexp, quel bonheur…

    … Oui, c'est de l'ironie. Les regexp n'ont de raccourcis que pour l'ASCII, donc pour les accents, il faut tout faire à la main. Il y a d'ailleurs une conversation sur le sujet qui a été plusieurs fois resortie, je réponds à tes autres questions et j'essaye de la retrouver

    D'abord le plus facile.
    Citation Envoyé par almoha Voir le message
    Que donnerait-elle en mode littéral ?
    En mode littéral, ta regexp devient ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /(?![^&;]+;)(?!<[^<>]*)(écoute)(?![^<>]*>)(?![^&;]+;)/gi
    Tu admettras que c'est pas beaucoup plus clair

    Citation Envoyé par almoha Voir le message
    Cette syntaxe avec le mot recherché entre parenthèses, encadré par des patterns elles-mêmes entre parenthèses, est-elle habituelle ?
    Non, mais chaque pattern est unique. Toutefois, je connais cette syntaxe et je m'en suis déjà servi.

    Citation Envoyé par almoha Voir le message
    Que fait exactement cette REGEX ?
    Il y a une chose à savoir à propos des parenthèses dans les regexp, c'est qu'elles peuvent être capturantes ou non capturantes. Par défaut, elles sont capturantes, c'est le cas du groupe (écoute) dans ton exemple. Les parenthèses capturantes permettent de garder une référence sur une portion de texte intéressante. Cette référence est ajoutée au tableau de résultat quand on utilise match, par exemple :
    Code console : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> "abc".match(/a(b)c/);
    ["abc", "b"]
    Utilisées avec replace, les parenthèses capturantes permettent de réutiliser les bouts de texte mémorisés, avec le symbole dollar. C'est comme ça que le "$1" est remplacé par "écoute" dans ton exemple.

    Pour comprendre ce que fait le reste de la regexp, séparons les différents groupes.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    a. (?![^&;]+;)
    b. (?!<[^<>]*)
    c. (écoute)
    d. (?![^<>]*>)
    e. (?![^&;]+;)
    Voilà une construction bizarre : (?! ... ). C'est une assertion négative. Les assertions (en anglais lookahead, littéralement « regarder en avant ») sont des bouts de regexp qui ne sont pas gardés dans le résultat. Par exemple, /a(?!b)/ signifie « "a" non suivi de "b" ». Si tu donnes la chaîne "ac" à cette regexp, elle te renverra simplement "a".
    Donc, le groupe a. signifie :
    Quelque chose qui n'est pas : la plus longue chaîne possible contenant au moins un carctère et ne contenant pas "&" ou ";", suivie de ";"
    J'imagine que ce groupe permet de vérifier que la portion de texte analysée ne fait pas partie d'une entité HTML comme &nbsp;.

    Une fois qu'une assertion a été vérifiée, elle est complètement oubliée par le moteur de regexp. Celui-ci revient en arrière, à l'endroit où il était quand il a commencé l'assertion. On dit parfois que les assertions ont une longueur 0. Ainsi, le moteur va rembobiner tout ce qu'il a lu pendant le groupe a. avant de vérifier le groupe b.
    Le groupe b., quant à lui, signfie :
    Quelque chose qui n'est pas : "<" suivi de la plus longue chaîne possible ne contenant pas "<" ou ">"
    Ce groupe vérifie qu'on n'est pas dans une balise HTML fraîchement ouverte.

    Ensuite, on rembobine à nouveau et on arrive au groupe c. : on regarde si la portion analysée correspond au texte à mettre en surbrillance.

    Vient le groupe d., qui fait l'inverse de b. : il regarde s'il n'y a pas une fermeture de balise après le mot-clé.

    Enfin, le groupe e. fait la même chose que a., après le mot-clé.

    Pour résumer, cette regexp trouve le mot-clé recherché dans une portion de texte non HTML, c'est-à-dire pas dans une balise et pas dans une entité.


    Voilà la conversation moultes fois ressassée à propos des accents :
    http://www.developpez.net/forums/d11...js-navigateur/

  3. #3
    Membre actif
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 388
    Points : 209
    Points
    209
    Par défaut
    Merci beaucoup pour ces explications aussi claires que complètes Excellent.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 07/05/2010, 11h22
  2. [RegEx] Compréhension regex
    Par Alixe80 dans le forum Langage
    Réponses: 1
    Dernier message: 13/02/2010, 11h26
  3. Réponses: 2
    Dernier message: 20/07/2009, 11h04
  4. Meilleur Compréhension des Regex
    Par islogged dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 05/06/2008, 10h27
  5. Personnalisation etat avant impression
    Par sibou51 dans le forum Access
    Réponses: 2
    Dernier message: 11/07/2006, 20h03

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