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 :

re.match et match multiple


Sujet :

Python

  1. #1
    Membre éclairé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Billets dans le blog
    1
    Par défaut re.match et match multiple
    Bonjour,

    une petite question de débutant au sujet de re.match :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import re
    line = 'param   =  123 spam and eggs'
    print re.match('(\w+)\s*=(\s*\w+)*',line ).groups()
    >>>('param', ' eggs')
    Pourquoi n'obtiens-je pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    >>>('param', '  123', ' spam', ' and', ' eggs')
    Le match semble ne garder que le dernier des (\s*\w+).
    Est-ce bien le cas, ou ai-je raté quelque chose ?

    Je pense que findall est fait pour ce genre de cas, mais à cause du '=', je suis obligé de matcher en 2 temps... c'est moche...
    Y a-t-il un moyen plus élégant ?

    Merci d'avance !

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Je pense que match n'est pas adapté, il recherchera la 1ère occurence recherchée me semble-t-il.

    J'utiliserais findall dans ton cas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import re
    line = 'param   =  123 spam and eggs'
    print re.findall('(\w+)',line )

  3. #3
    Membre éclairé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Billets dans le blog
    1
    Par défaut
    Oui, merci, mais ce pattern va matcher beaucoup trop de choses.
    Par ex. : 'param ; 123 = spam ++= and <?> eggs'

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Oui, merci, mais ce pattern va matcher beaucoup trop de choses.
    Que des groupes de caractères.

    T'as testé?

    Ton contre exemple me renvoi ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ['param', '123', 'spam', 'and', 'eggs']
    ?

  5. #5
    Membre éclairé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Billets dans le blog
    1
    Par défaut
    Si le re.match marchait comme je l’espérait, mon pattern (\w+)\s*=(\s*\w+)* ne matcherait que des groupes de caractères alphanumériques séparés par des espaces avec un '=' entre le premier et les suivants.
    Et donc, il ne matcherait pas mon contre-exemple.
    C'est ce que je voulais dire par "matcher beaucoup trop de choses".

  6. #6
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Oui, mais match (et les regex de façon générale) ne marchent pas comme ça –*sinon, il n’y aurait plus moyen de faire référence aux groupes capturés par leur numéro*! Donc, dans le cas où un groupe de capture est/peut être répété, ce sera toujours la dernière occurrence qui sera capturée in fine

    Je ne vois que deux solutions. La méthode bourrin (et encore, à condition que le nombre d’éléments à capturer après le signe égal soit connu et raisonnable)*:

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    re.match(r'(\w+)\s*=(\s*\w+)?(\s*\w+)?(\s*\w+)?(\s*\w+)?{etc.}', line).groups()

    groups() renverra des items vides/NULL pour les groupes n’ayant rien capturé.

    Ou alors, la double détente, par exemple*:

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    key, val = re.match(r'(\w+)\s*=((?:\s*\w+)*)', line).groups()
    vals = val.split() # ou un findall quelconque, si split() ne suffit pas…

    PS*: n’oublie pas le r des string raw, si tu ne veux pas doubler tous tes backslashs*!

  7. #7
    Membre éclairé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Billets dans le blog
    1
    Par défaut
    Merci mont29

    J'avais senti venir le coup et j'ai déjà une solution à base de match puis findall.
    (le split ne suffit car mon pattern est plus compliqué que celui de mon exemple (fabriqué pour ce post))

    Merci pour la précision à propos du r des raw strings, mais c'est juste dans mon petit cas d'exemple que je l'avais oublié

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

Discussions similaires

  1. array $matches[0] / $matches[1], récupérer l'une des valeurs du tableau
    Par Globolite dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 4
    Dernier message: 06/05/2014, 14h48
  2. Réponses: 2
    Dernier message: 22/12/2003, 15h23
  3. Requete select pour récupérer les no match entre 2 tables
    Par Celina dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 16/12/2003, 11h59
  4. "Match nul"
    Par Sylvain James dans le forum XML/XSL et SOAP
    Réponses: 4
    Dernier message: 17/06/2003, 10h27
  5. template match="node() mais pas text()"
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 26/03/2003, 10h52

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