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

Python Discussion :

Décrypter une regex


Sujet :

Python

  1. #1
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut Décrypter une regex
    Bonsoir,
    que signifie la regex suivante ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _ws = r'(?:\s|//.*?\n|/[*].*?[*]/)+'
    Existe-t-il des outils qui donnent des exemples "concrets" permettant de visualiser ce que représente une regex ? Je sais qu'il existe un outil sous Linux mais j'ai oublié son nom.

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    r'(?:\s|//.*?\n|/[*].*?[*]/)+'

    (?: ) définit un groupe non capturant.

    Ce groupe est composé de 3 sous-groupes:
    \s

    //.*?\n

    /[*].*?[*]/

    le caractère | étant un caractère spécial signifiant OU.

    C’est cette alternance de sous-groupes qui oblige à mettre des parenthèses pour limiter l’extension du OU à droite aussi bien qu’à gauche. Seuls un début ou une fin de chaîne , ou des parenthèses constituent en effet les bornes jusqu’où va un morceau de chaîne participant à un OU.




    Le + à la fin dit que le contenu de la RE non capturante peut se répéter plusieurs fois , c’est à dire qu’une chaîne matchante pourra comporter la répétition des 3 sous-groupes.
    Les 3 sous-groupes pourront se succéder en alternance/répétition, pas seulement un seul répété.
    Ainsi cette RE est elle par exemple équivalente à
    \s+/[*].*?[*]//[*].*?[*]//[*].*?[*]/ //.*?\n
    entre autres multiples possibilités combinatoires.



    * est placée dans [*] pour représenter simplement le caractère étoile parce que les caractères spéciaux perdent leur spécialisation dans la définition d’un ensemble




    //.*?\n peut être simplifiée en //.*\n si la regex est créée sans mode MULTILINE. Dans ce cas, en effet, le point ne matche pas les fins de lignes et .*\n s’arrêtera automatiquement à la première fin de ligne.



    Pour vérifier sans modifier sa nature de groupe non capturant que cette RE agit bien comme je le décris,
    je l’insère dans une RE plus large pour prendre des exemples.



    Vérification du OU:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    import re
     
    ch = 'oued\tsoleil tomate'\
         +'fred//google.com aristide\nsoleils noirs'\
         +'farad/* camille golf au */soleil faible'
     
    pat = re.compile(r'd(?:\s|//.*?\n|/[*].*?[*]/)(soleil.{7})')
    print pat.findall(ch)
    ['soleil tomate', 'soleils noirs', 'soleil faible']



    Vérification de la répétition:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    import re
     
    ch = 'oued\t\n\t\t\t\t\t    \r\n soleil tomate'\
         +'fred//google.com aristide\n//ziuiui.fr.blon\nsoleils noirs'\
         +'farad/*camille*//*clairon*//*boite*//*orange*/soleil faible'
     
    pat = re.compile(r'd(?:\s|//.*?\n|/[*].*?[*]/)+(soleil.{7})')
    print pat.findall(ch)
    ['soleil tomate', 'soleils noirs', 'soleil faible']


    Vérification que les 3 motifs peuvent alterner:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import re
     
    ch = 'oued\t\n//google.com aristide\n\t\t\t\t\t  /*boite*//*orange*/  \r\n'\
         +'\t\t\t\n\n   \r /*boite*//*orange*/'\
         +'//ziuiui.fr.blon\n\n\n\n\n\n\n\n//<class ="rien">\n\t\n\t\t'\
         +'/*camille*//*clairon*/soleil helios'
     
    pat = re.compile(r'd(?:\s|//.*?\n|/[*].*?[*]/)+(soleil.{7})')
    print pat.findall(ch)
    ['soleil helios']

    Vérification que la chaîne matchante ne doit pas comporter de parasites entre les motifs matchant avec les sous-groupes:

    ch = 'oued\t\n//google.com aristide\n\t\t\tDODO\t\t/*climat*/ \r\n'\
    +'\t\t\t\n\n \r /*boite*//*orange*/'\
    +'//ziuiui.fr.blon\n\n\n//<class ="rien">\n\t\n\t\t'\
    +'/*camille*//*clairon*/soleil helios'

    ne matche pas



    ch = 'oued\t\n//google.com aristide\n\t\t\t\t\t/*climat*/ \r\n'\
    +'\t\t\t\n\n \r /*boite*//*orange*/'\
    +'//ziuiui.fr.blon\n\n\nYwYwYwYwYw//<class ="rien">\n\t\n\t\t'\
    +'/*camille*//*clairon*/soleil helios'

    ne matche pas.



    Par contre,

    ch = 'oued\t\n//google.com aristide\n\t\t\t\t\t/*climat*/ \r\n'\
    +'\t\t\t\n\n \r /*boite*//*orange*/'\
    +'//ziuiui.fr.blon\n\n\n//<class ="rien">\n\t\n\t\t'\
    +'/*camille*/ABABABABAB/*clairon*/soleil helios'

    matche quand même , parce que /[*].*?[*]/ commence à matcher à /*camille puis le point continue de matcher */ABABABABAB/*clairon et enfin [*]/ matche avec */. Ce qui veut dire que quand on n’a pas un signal d’arrêt fort pour un point, même écrit .+?, la regex poursuit allègrement son matching au delà du premier signal d’arrêt rencontré et va jusu’au dernier possible. Dans ce genre de cas, quand on construit la RE, on arrive à un stade qui donne la réponse attendue et on croït alors qu’on a trouvé la bonne RE. Ce n’est pas le cas, et c’est alors que si une situation comme /*camille*/ABABABABAB/*clairon*/ se présente, elle passera pour OK alors qu’elle ne correspond pas à ce qui est attendu.

    Donc en dehors d’un signal d’arrêt \n pour le point en mode non multiligne, il vaut mieux écrire un ensemble défini par complémentation pour arrêter une consommation gloutonne d’un symbole polyvalent.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import re
    
    ch = 'oued\t\n//google.com aristide\n\t\t\t\t\t/*climat*/  \r\n'\
         +'\t\t\t\n\n   \r /*boite*//*orange*/'\
         +'//ziuiui.fr.blon\n\n\n//<class ="rien">\n\t\n\t\t'\
         +'/*camille*/ABABABAB/*clairon*/soleil helios'
    
    pat = re.compile(r'd(?:\s|//.*?\n|/[*][^*]*[*]/)+(soleil.{7})')
    
    print pat.findall(ch)
    ['soleil helios']
    ne capture rien, comme attendu, et l’enlèvement de ABABABABAB rétablit une capture correcte.


    ------------------------------


    Il y a un site qui est très bien pour les explications sur les regex. Il propose un logiciel de test , PowerGREP , gratuit en essai de 15 jours, puis achetable 129 euros.

    http://www.regular-expressions.info/powergrep.html

  3. #3
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Merci pour ces explications très détaillées...

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

Discussions similaires

  1. [Sécurité] Clef pour crypter et décrypter une var
    Par maty2006 dans le forum Langage
    Réponses: 5
    Dernier message: 25/06/2006, 17h49
  2. Problème avec une RegEx
    Par Death83 dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 26/05/2006, 14h03
  3. Insérer une variable dans une regex?
    Par Death83 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 21/05/2006, 11h28
  4. [RegEx] php et javascript dans une regex
    Par grochenel dans le forum Langage
    Réponses: 7
    Dernier message: 06/12/2005, 22h21
  5. [RegEx] spliter par rapport a une regex en récuperant la regex
    Par Khrysby dans le forum Langage
    Réponses: 1
    Dernier message: 10/11/2005, 15h08

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