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 :

Pattern Regex avec condition [Python 3.X]


Sujet :

Python

  1. #1
    Membre habitué
    Homme Profil pro
    Webdesigner
    Inscrit en
    Novembre 2010
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Novembre 2010
    Messages : 9
    Par défaut Pattern Regex avec condition
    Bonjour à tous,

    Mes données:
    Des PDF numériques

    Mon objectif:
    Créer des Pattern Regex pour sélectionner les éléments dont j'ai besoin dans les PDF (cela fonctionne déjà bien)

    Mon problème:
    Je voudrais savoir si je peux introduire une condition dans un pattern. Voici par exemple mon problème: j'ai de temps en temps du contenu qui, à cause de sa longueur, fait un retour à la ligne alors que la majorité du temps ça n'est pas le cas. Ce cas se produit s'il s'agit d'un produit unitaire et donc avec la phrase "votre commande à une valeur de". Est-il possible de ne faire qu'un seul pattern au lieu de deux ?

    Du coup, mon pattern (sans retour à la ligne) est de type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    pattern_pieces['retour']=
    '(?P<Quantite>\d+) ('vos commandes pour un montant de|vos commandes sont') . ' \
    '(?P<Montant>\d*[.]?\d+[,]\d{2})\\n' \

    Mais, si j'ai un retour à la ligne alors mon pattern serait plutôt:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    pattern_pieces['retour']=
    '(?P<Quantite>\d+) ("votre commande à une valeur de") .\\n ' \ #je dois ici ajouter un saut de ligne
    '(?P<Montant>\d*[.]?\d+[,]\d{2})\\n' \

    Merci à vous,

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 690
    Par défaut
    Citation Envoyé par vuvu960 Voir le message
    Est-il possible de ne faire qu'un seul pattern au lieu de deux ?
    Tout dépend comment on pose le problème: si on dit qu'on cherche à matcher un pattern de la forme AXE ou AYE, plutôt que d'écrire 2 regexp, on va écrire 'A(X|Y)E)'. Idée à appliquer à votre cas particulier.... en notant qu'un forum Python n'a rien à voir avec le mini-langage des expressions régulières.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 814
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par vuvu960 Voir le message
    Je voudrais savoir si je peux introduire une condition dans un pattern.
    Pas dans le peu que je connais des regex.
    Mais tu peux parfaitement introduire une condition dans la création d'une variable. Style variable="xxx" if expression else "yyy". A toi de trouver l'expression qui détecte "retour de ligne présent ou pas" pour créer le bon pattern.

    Citation Envoyé par vuvu960 Voir le message
    Mais, si j'ai un retour à la ligne alors mon pattern serait plutôt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    pattern_pieces=['retour']=
    '(?P<Quantite>\d+) ("votre commande à une valeur de") .\\n ' \
    '(?P<Montant>\d*[.]?\d+[,]\d{2})\\n' \
    Ecrire variable=["string"]=valeur n'est pas autorisé. Et es-tu sûr de l'accent pour le "à" ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre habitué
    Homme Profil pro
    Webdesigner
    Inscrit en
    Novembre 2010
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Novembre 2010
    Messages : 9
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Tout dépend comment on pose le problème: si on dit qu'on cherche à matcher un pattern de la forme AXE ou AYE, plutôt que d'écrire 2 regexp, on va écrire 'A(X|Y)E)'. Idée à appliquer à votre cas particulier.... en notant qu'un forum Python n'a rien à voir avec le mini-langage des expressions régulières.

    - W
    tout à fait d'accord, je me suis trompé de section. désolé aux admins.

    Par contre, bien que je comprends votre exemple AXE ou AYE comment comment l'appliquer dans mon cas dans la mesure ou ce n'est pas ça ou ça mais plutôt si c'est ça alors tu dois faire un saut de ligne. L'idée n'est pas d'avoir 2 ou 3 choix possibles mais que s'il s'agit d'un des trois choix alors il faudra faire un saut à la ligne mais pas pour les deux autres.

  5. #5
    Membre habitué
    Homme Profil pro
    Webdesigner
    Inscrit en
    Novembre 2010
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Novembre 2010
    Messages : 9
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Bonjour

    Pas dans le peu que je connais des regex.
    Mais tu peux parfaitement introduire une condition dans la création d'une variable. Style variable="xxx" if expression else "yyy". A toi de trouver l'expression qui détecte "retour de ligne présent ou pas" pour créer le bon pattern.


    Ecrire variable=["string"]=valeur n'est pas autorisé. Et es-tu sûr de l'accent pour le "à" ???
    désolé erreur de frappe, je corrige le premier post

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 690
    Par défaut
    Citation Envoyé par vuvu960 Voir le message
    comment l'appliquer dans mon cas dans la mesure ou ce n'est pas ça ou ça mais plutôt si c'est ça alors tu dois faire un saut de ligne.
    Le but d'une expression régulière est de vérifier la conformité d'une chaine de caractères à un pattern pour en extraire des informations pertinentes pas de générer du texte.
    "faire un saut de ligne" n'a aucun sens ici: ça "matche" avec ou sans...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre habitué
    Homme Profil pro
    Webdesigner
    Inscrit en
    Novembre 2010
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Novembre 2010
    Messages : 9
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Le but d'une expression régulière est de vérifier la conformité d'une chaine de caractères à un pattern pour en extraire des informations pertinentes pas de générer du texte.
    "faire un saut de ligne" n'a aucun sens ici: ça "matche" avec ou sans...

    - W
    oui je suis bien d'accord avec vous, le problème c'est que si pour ce "MATCH" précis je n'applique pas le saut de ligne présent dans mon PDF ça ne fonctionne pas et si je l'ajoute comme dans mon premier post (deuxième cas), ça fonctionne.

    Mais je me dis qu'il doit y avoir moyen de solutionner tout ça dans un seul pattern et pas d'en faire deux mais peut-être que je me trompe?

  8. #8
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 191
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 191
    Par défaut
    Hello,
    il faudrait que tu nous donnes un échantillon représentatif de la chaîne source pour pouvoir voir ce que l'on peut faire.

    Avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import re
    source = """
    vos commandes pour un montant de 10 euros
    vos commandes sont de 400 euros
    votre commande à une valeur de
    2000 euros
    """
    motif = "(vos commandes pour un montant de|vos commandes sont|votre commande à une valeur de)[\s\w\n]+?(?P<Montant>\d+)"
    match = re.findall(motif, source,re.MULTILINE)
    print(match)
    j'obtiens ceci :
    [('vos commandes pour un montant de', '10'), ('vos commandes sont', '400'), ('votre commande à une valeur de', '2000')]
    Ami calmant, J.P

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 690
    Par défaut
    Citation Envoyé par vuvu960 Voir le message
    Mais je me dis qu'il doit y avoir moyen de solutionner tout ça dans un seul pattern et pas d'en faire deux mais peut-être que je me trompe?
    Vous vous trompez... mais, si vous ne savez pas faire avec, essayer de faire sans avec le python que vous maîtrisez.

    note: une expression régulière s'utilise comme argument d'une fonction du module re.... qu'on peut toujours emballer dans une fonction à soi qui ait la même interface mais qui fera plus pas à pas.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 814
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par vuvu960 Voir le message
    Mais je me dis qu'il doit y avoir moyen de solutionner tout ça dans un seul pattern et pas d'en faire deux
    En quoi serait-ce gênant d'en faire deux???
    Regarde comment on peut associer la puissance de Python dans l'exemple de jurassic pork...
    Code python : 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
    import re
    source = """
    vos commandes pour un montant de 10 euros
    vos commandes sont de 400 euros
    votre commande a une valeur de
    2000 euros
    """
     
    patterns=(
    	"vos commandes pour un montant de",
    	"vos commandes sont",
    	"votre commande a une valeur de",
    )
     
    motif = "(%s)[\s\w\n]+?(?P<Montant>\d+)" % "|".join(patterns)
    match = re.findall(motif, source, re.MULTILINE)
    print(match)

    Tu as d'autres patterns posibles? Tu les rajoutes simplement dans le tuple. Tu veux faire ça plus configurable? Tu mets tes pattern dans un fichier texte que tu lis au départ pour les stocker dans un tuple tel que j'ai créé mon "patterns"
    Et dans tous les cas, Python réajuste tout ça automatiquement pour en faire une regex propre...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  11. #11
    Membre habitué
    Homme Profil pro
    Webdesigner
    Inscrit en
    Novembre 2010
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Novembre 2010
    Messages : 9
    Par défaut
    Merci à jurassic pork et Sve@r et tous les autres vous avez bien compris mon problème. Merci pour votre aide, je passe en résolu.

  12. #12
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 985
    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 985
    Par défaut
    Une pattern ça peut être souple. Visiblement ce qui t'intéresse c'est la quantité et le montant (les deux groupes que tu as pris la peine de nommer), on se fiche de savoir combien et de quelle nature sont les "caractères blancs" qui séparent les différents éléments, autant rester évasif et utiliser \s+:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pattern = '(?P<Quantite>\d+)\s+(?:vos commandes pour un montant de|vos commandes sont|votre commande a une valeur de)\s+(?P<Montant>\d*[.]?\d+,\d\d)\n'
    Tu pourrais même pousser le bouchon jusqu'à réduire la précision sur les phrases au milieu (en restant raisonnable):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pattern = '(?P<Quantite>\d+)\s+vo\w* commandes? (?:\w+ )+?(?:de|sont)\s+(?P<Montant>\d*[.]?\d+,\d\d)\n'
    (vo...commande...de/sont) ça doit être suffisamment discriminant pour éviter les faux positifs; au pire tu changes (?:\w+ )+? pour (?:\w+ ){1,3}.

  13. #13
    Membre habitué
    Homme Profil pro
    Webdesigner
    Inscrit en
    Novembre 2010
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Novembre 2010
    Messages : 9
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    Une pattern ça peut être souple. Visiblement ce qui t'intéresse c'est la quantité et le montant (les deux groupes que tu as pris la peine de nommer), on se fiche de savoir combien et de quelle nature sont les "caractères blancs" qui séparent les différents éléments, autant rester évasif et utiliser \s+:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pattern = '(?P<Quantite>\d+)\s+(?:vos commandes pour un montant de|vos commandes sont|votre commande a une valeur de)\s+(?P<Montant>\d*[.]?\d+,\d\d)\n'
    Tu pourrais même pousser le bouchon jusqu'à réduire la précision sur les phrases au milieu (en restant raisonnable):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pattern = '(?P<Quantite>\d+)\s+vo\w* commandes? (?:\w+ )+?(?:de|sont)\s+(?P<Montant>\d*[.]?\d+,\d\d)\n'
    (vo...commande...de/sont) ça doit être suffisamment discriminant pour éviter les faux positifs; au pire tu changes (?:\w+ )+? pour (?:\w+ ){1,3}.
    Wow c'est bon ça, merci pour ce détail, ça va m'aider, top !

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

Discussions similaires

  1. Pattern : Regex avec un nombre de caractères spécifiques uniques
    Par orage878 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 23/07/2018, 23h53
  2. [RegEx] Regex avec condition
    Par yudao dans le forum Langage
    Réponses: 6
    Dernier message: 29/05/2007, 15h08
  3. ALTER VIEW avec condition
    Par yan77 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 05/04/2004, 17h22
  4. Index avec conditions
    Par marhnix dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 29/03/2004, 10h48
  5. boucle avec condition d'arret changeante
    Par NicoH dans le forum Langage
    Réponses: 3
    Dernier message: 10/06/2003, 11h48

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