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 :

[Python] Regex d'intro


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Points : 10
    Points
    10
    Par défaut [Python] Regex d'intro
    Bonjour,


    Je me mets à Python, en commençant par l'utilisation des regex.
    L'un des buts de mon projet est de parcourir des fichiers sources C et de remplacer mes affectation de variables, par des appels à une fonction qui fera l'écriture dans la variable.
    Pas besoin de me dire que c'est idiot, que ça ne sert à rien, qu'on doit pas faire ça... les projets sont ce qu'ils sont, et mon besoin est là.
    J'ai énormément de mal avec les regex, malgré la lecture de doc; j'ai du mal à trouver un tutoriel simple et limpide... bref, je perds un peu espoir.

    J'ai donc une fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    def fonctionRegex(input_var, var_id)
    , dont le rôle est de remplacer toutes les affectations de valeur par un appel à une fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WriteValue(var_id, value)
    , (value étant la valeur à donner, située précédemment après le égal de l'affectation).


    Je ne comprends pas comment, dans une chaine de caractère (une ligne de code C dans mon cas), je peux :
    • détecter l'affectation "input_var=qq_chose" ou "input_var = qq_chose"
    • que mon expression régulière place le "qq_chose" dans une variable réutilisable (jusque là j'utilise "find", mais ça ne récupère pas le "qq_chose")
    • générer la chaine de sortie

    Le plus gros problème, c'est surtout de détecter ce qui suit le égal : parfois une variable, parfois un appel à une fonction retournant une valeur...

    Si vous pouviez me donner des pistes (je ne demande pas qu'on me le fasse) pour réaliser cette fonction de remplacement parce que là, je rame un peu..., d'autant que c'est un bon moyen de se mettre aux regex sous Python


    Merci d'avance pour votre aide

    Nicolo

  2. #2
    Membre extrêmement actif
    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
    Points : 1 658
    Points
    1 658
    Par défaut
    Bonjour,



    Pour détecter "input_var=qq_chose" ou "input_var = qq_chose", il faut écrire une regex à partir d’une RE:
    personnellement , j’appelle RE une chaîne de Regular Expression
    et regex un objet RegexObject.

    pattern = re.compile(’input_var ?= ?(.+?)’)

    Dans cette instruction
    ’input_var ?= ?(.+?)’ est la RE
    et pattern est la regex.

    Une regex est un RegexObject , à bien distinguer de la RE et d’un MatchObject.
    Un RegexObject est un objet qui sert à rechercher des motifs matchant avec la RE dans une chaîne explorée.
    Un MatchObject est un objet contenant les renseignements relatifs à un match, c’est à dire à un motif matchant donné après qu’il ait été trouvé dans la chaîne explorée.


    ’ ?’ signifie : un blanc ou pas de blanc
    ( il y a un blanc devant le ’?’ )

    les ( ) autour de .+? définissent un groupe c’est à dire qu’elles permettent l’enregistrement, dans le MatchObject, de la chaîne matchante qui sera trouvée à l’emplacement de (.+?) dans la chaîne examinée.

    Le point . signifie: n’importe quel caractère, hormis une fin de ligne (sauf spécification contraire).

    .+ signifie: n’importe quel caractère répété une fois ou plus (on part du principe qu’il y a au moins un caractère après ’input_var ?= ?’ )

    Dans .+? , le ’?’ est là pour intimer au moteur de regex d’arrêter d’avancer en enregistrant les caractères rencontrés dès qu’il rencontrera le caractère qui suit (.+?) . Si on ne controle pas ainsi, le moteur de regex est en effet glouton et mange tant qu'il peut.

    Mais !...il n’y a pas de caractère après (.+?) dans la cette RE !
    Eh oui !
    C’est parce que ta description est incomplète: il faut absolument indiquer quelle est l’extension du qq_chose dont tu parles, c’est à dire où s’arrête le qq_chose, comment reconnaît on la fin du qq_chose.

    Je crois qu’en C et C++, les instructions se terminent par ’;’. Si c’est le cas et que ’;’ colle au qq_chose, on écrira la RE:
    pattern = re.compile(’input_var ?= ?(.+?);’)

    Mais s’il y a un blanc après le qq_chose , et que le qq_chose ne comporte pas de blanc !, on écrira
    pattern = re.compile(’input_var ?= ?(.+?) ’)

    Enfin bon, les cas de figure sont infinis.




    Une fois que le moteur de regex aura détecté un match et créé un MatchObject pour le représenter (pour cela il y a plusieurs fonctions utilisables, on verra ça plus tard, on va se contenter de search() pour le moment ), on peut interroger le MatchObject pour en tirer divers renseignements.

    Appelons m le MatchObject.
    Pour obtenir le tuple des groupes capturés dans m, on fait m.groups()

    Pour obtenir la chaîne matchante dans son entier, c’est m.group() , égal par défaut à m.group(0).

    Quant aux groupes individualisés, on les obtient par m.group(i) avec i de 1 à nombre de groupes définis.

    Dans notre RE, on n’a qu’un groupe, on l’obtient par m.group(1)
    Ou m.groups()[0] .... eh oui, c’est un truc tordu, c’est comme ça.





    Bon, j’arrête là pour le moment, j’attends ton retour pour savoir si ça t’éclaire. Et je cherche à comprendre la suite.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Bonjour,

    Je te remercie énormément, parce que tu as répondu à ma question avec énormément de clarté (enfin une explication claire sur les regex).

    ça marche du feu de dieu; avec ma regex, je fais ensuite l'appel à la méthode match() ou search() afin de placer les objets trouvés dans un matchobject.
    L'appel ensuite à groups() me donne les éléments.

    Jusque là, très clair, je commence à m'amuser.

    Je pense ensuite faire le remplacement de ma ligne de code par l'appel à la méthode qui m'intéresse; du genre :
    input_var=value qui devient WriteValue(var_id, value)
    ... value est connu, puisque m.groups()[0] le contient
    Je pensais utiliser la fonction replace des string, mais j'ai l'impression que le replac ne prend pas les expresions regulières en paramètres, mais juste des chaines...

    une idée?


    Merci d'avance

    Nicolo

    PS :
    Pour laisser une petite trace si d'autres lisent cette discussion un de ces jours, je liste des exemples d'essais :

    • Premier cas : affectation sans espaces

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
       
      >>> lignedecode="variable=2"
      >>> regexobjectnico=re.compile('variable=(.+?)')
      >>> matchobjectnico=regexobjectnico.match(lignedecode)
      >>> matchobjectnico.groups()
      ('2',)
    • Deuxième cas : avec espaces éventuels de part et d'autre du '=' et prise en compte du point virgule final
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
       
      >>> regexobjectnico=re.compile('variable ?= ?(.+?);')
      >>> matchobjectnico=regexobjectnico.match(lignedecode)
      >>> matchobjectnico.groups()
      ('2',)

  4. #4
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    bonjour,

    tu peux aussi utiliser la méthode sub:

    http://docs.python.org/library/re.html#re.sub

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    105
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2007
    Messages : 105
    Points : 145
    Points
    145
    Par défaut
    Bonjour,

    Evidemment les parenthèses peuvent être présente partout pour pouvoir, par exemple, récupérer le nom de la variable ainsi que son affectation.
    Si jamais, je te conseil un petit tour chez ton ami avec par exemple comme comme mot clef: regexbuilder
    Tu trouveras plusieurs outils te permettant de faire et de tester tes expressions régulières.

    Salutations.

Discussions similaires

  1. RegEx et Python
    Par benoxy dans le forum Général Python
    Réponses: 7
    Dernier message: 20/09/2011, 20h05
  2. [RegExp] Une regex Python en Javascript
    Par ____22 dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 05/08/2011, 17h15
  3. Regex en python
    Par greg1517 dans le forum Général Python
    Réponses: 5
    Dernier message: 12/10/2009, 15h55
  4. regex : différence entre Perl et Python
    Par rambc dans le forum Général Python
    Réponses: 3
    Dernier message: 08/01/2009, 20h53
  5. python et regex
    Par olaxius dans le forum Général Python
    Réponses: 2
    Dernier message: 15/11/2006, 14h02

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