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 :

aide pour pattern REGEX


Sujet :

Python

  1. #1
    Membre averti
    Homme Profil pro
    geek
    Inscrit en
    Mai 2017
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : geek
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2017
    Messages : 44
    Par défaut aide pour pattern REGEX
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    import re
     
    with open("extract.txt", "r", ) as fic:
        for test_str in fic:
            r1 = re.findall(r"[D]\d+[.| ]{0,1}\d+[.| ]{0,1}\d+", test_str)
            if len(r1) == 1:
                print (r1)
    Bonsoir
    je cherche a extraire des séquences de caractères écrites sous cette forme
    idéalement c'est ca:
    D12312345123 (1lettre, 3+5+3 chiffres)


    mais le texte peut aussi contenir des choses écrites différemment comme
    D123-12345.123
    d123.12345123
    D123 12345 123
    ou des choses incorrectes, incomplètes
    D12-12345.123

    Comment écririez vous le pattern regex, pour tout détecter ?

  2. #2
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    Une façon simple serais que de plutôt vérifier pour beaucoup trop de cas difficilement généralisable en 1regex de dans un premier temps enlever tout ce qui n'est ni lettre ni chiffre, puis après de vérifier que la chaine correspond bien au pattern 1 lettre 3+5+3 chiffres

    Sinon l'opérateur ? Équivaut à {0,1}, une fois les caractères superflus enlevés le pattern sera [a-Z]\d{8}

  3. #3
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2004
    Messages : 253
    Par défaut
    Bonjour,

    Je plusoie flapili à un détail près: s'il y a toujours un séparateur entre les groupes de chiffres et que ces groupes ont un sens, supprimer tout ce qui n'est pas lettre ou chiffre avec des choses incorrectes peut amener à des faux positifs.
    Ex: D12.345-986523
    Tu peux essayer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    r'([a-zA-Z])(\d{3})[. -]?(\d{5})[. -]?(\d{3})'

  4. #4
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    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 986
    Par défaut
    Citation Envoyé par flapili Voir le message
    Sinon l'opérateur ? Équivaut à {0,1}, une fois les caractères superflus enlevés le pattern sera [a-Z]\d{8}
    Par contre [a-Z] (de même que [A-z]) n'équivaut pas du tout à [a-zA-Z], c'est même un intervalle invalide car le caractère a est situé après le caractère Z dans la table ascii.

    Un petit test: re.findall(r'[A-z]', '[\]^_`')
    Citation Envoyé par daniel-12
    [.| ]
    Dans une classe de caractères, le | perd son sens spécial et ne signifie plus OR. D'une manière générale, les caractères avec un sens spécial dans la pattern le perdent dans les classes de caractères et sont vus comme de simples caractères, mis à part l'antislash. En revanche les classes de caractères ont des caractères spéciaux qui leur sont propres: ^ - ].

  5. #5
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    En effet j'était sur portable je suis allez un peu vite

  6. #6
    Membre averti
    Homme Profil pro
    geek
    Inscrit en
    Mai 2017
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : geek
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2017
    Messages : 44
    Par défaut
    Merci a tous pour vos réponses. je vais les tester.

    j'ai l'impression que les regex fait sous VBA et python, sont écrit légèrement différemment
    je me trompe?

    et le site regex101 pour les test, il vous semble fiable ?

  7. #7
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    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 986
    Par défaut
    Les regex VBA (VBScript) et Python ont exactement la même syntaxe (héritée de Perl 5 comme énormément de langages), les différences sont plutôt en terme de fonctionnalités disponibles, par exemple les regex VBA n'ont pas de test arrière entre autres. Si tu veux de l'exotisme en matière de syntaxe et de comportement essaie grep (qui utilise par défaut la syntaxe BRE) ou Perl 6 (qui a une toute nouvelle syntaxe).

    regex101 est un très bon outil, bien sûr il faut veiller à choisir le bon langage avant de commencer.

  8. #8
    Membre averti
    Homme Profil pro
    geek
    Inscrit en
    Mai 2017
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : geek
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2017
    Messages : 44
    Par défaut
    finalement je vais utiliser quelques chose de ce style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    r1 = re.findall(r"[DEF]\d+[.\-_ ]?\d+[.\-_ ]?\d+", test_str)
    a noter que je suis obligé de mettre un \ devant le -
    je n'ai pas trop compris pourquoi
    il me detecte ça
    ['D53.10000-000']
    ['D531100000000']
    ['D531-10000-000']
    ['D531.10000.000']
    ['D531 10000 000']
    ['D12.345-986523']

    et sans le \
    ['D53.10000']
    ['D531100000000']
    ['D531']
    ['D531.10000.000']
    ['D531 10000 000']
    ['D12.345']

    j'imagine que sans le slash c'est interprété comme caractères de . à _
    j'ai bon ?


    fifan31, ta proposition ne convient pas pour ce que je cherche
    r'([a-zA-Z])(\d{3})[. -]?(\d{5})[. -]?(\d{3})'
    [('D', '531', '10000', '000')]
    [('D', '531', '10000', '000')]
    [('D', '531', '10000', '000')]
    [('D', '531', '10000', '000')]
    sauf si bien sur les texte étaient tous bien ecrit avec le bon nombre de digits
    mais je veux justement détecter ceux qui sont trop courts ou longs

  9. #9
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    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 986
    Par défaut
    Tu as bon, c'est exactement ça. Pour te passer de l'antislash devant le -, il suffit de le placer au début ou à la fin de la classe de caractères, comme ça pas d'ambiguïtés possibles.

  10. #10
    Membre éprouvé Avatar de olivier1969
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Novembre 2013
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 153
    Par défaut
    Hello ,

    Ceci devrai fonctionner avec n'importe quel séparateur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    r1 = re.findall(r"([defDEF]\d+)\D?(\d+)\D?(\d+)",  test_str)

  11. #11
    Membre averti
    Homme Profil pro
    geek
    Inscrit en
    Mai 2017
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : geek
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2017
    Messages : 44
    Par défaut
    Bien vu le \D?

    mais j'aime bien avoir tout groupé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    r1 = re.findall(r"[defDEF]\d+\D?\d+\D?\d+", test_str)

  12. #12
    Membre éprouvé Avatar de olivier1969
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Novembre 2013
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 153
    Par défaut
    Citation Envoyé par daniel-12 Voir le message
    Bien vu le \D?

    mais j'aime bien avoir tout groupé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    r1 = re.findall(r"[defDEF]\d+\D?\d+\D?\d+", test_str)
    Du coup quel est l’intérêt du findall si tu conserves la totalité de la ligne ??
    Mais bon je ne vois pas le traitement que tu en fais ni d'où sont issues ces chaines de caractères, et peut être que les ^ et $ seraient nécessaires ... Bref les possibilités sont immenses !!

    Si tu as ce type de chaine par exemple "d152-d366.256.6556" , ça change tout !

  13. #13
    Membre averti
    Homme Profil pro
    geek
    Inscrit en
    Mai 2017
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : geek
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2017
    Messages : 44
    Par défaut
    a vrai dire si je vois ça: "d152-d366.256.6556" je detecte tout de suite le problème, visuellement
    c'est un peu comme si on lisait un code postal francais 7845451, ça cloche
    ou une plaque d'immatriculation 45-gh-45-78

    par contre, "d152-366256" c'est moins évident (il y a juste un chiffre de trop)
    idem pour celui ci D152366256

    dans un premier temps l'outil verra qu'il y a 6 chiffre
    et au controle suivant qui sera une comparaison par rapport a un dictionnaire, l'alerte sur cette erreur sera signalée

  14. #14
    Membre averti
    Homme Profil pro
    geek
    Inscrit en
    Mai 2017
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : geek
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2017
    Messages : 44
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    listep = []
    with open("c:/temp/temp3.txt", "r", ) as fic:
        for test_str in fic:
            r1 = re.findall(r"[DEF]\d+[.\-_ ]?\d+[.\-_ ]?\d+", test_str)
            if len(r1) == 1:
                listep.append(r1)
    print listep  #[['D53118662'], ['D53118662000']]
     
    listep1 = ['D53110000','D53110001']

    Bonsoir
    j'ai un petit soucis, pas avec la pattern que j'affinerai si besoin mais avec le résultat

    quand je trouve ce qui m'intéresse, je l'ajoute a une liste pour le traiter plus tard
    ça ressemble à ça : [['D53118662'], ['D53118662000']] avec des crochets en trop

    moi je voudrais ça : ['D53110000','D53110001']

    savez vous pourquoi, et surtout comment y remédier ?

  15. #15
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 725
    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 725
    Par défaut
    Citation Envoyé par daniel-12 Voir le message
    ça ressemble à ça : [['D53118662'], ['D53118662000']] avec des crochets en trop
    Ces "crochets" traduisent une liste de listes à un seul élément.

    Citation Envoyé par daniel-12 Voir le message
    moi je voudrais ça : ['D53110000','D53110001']
    savez vous pourquoi, et surtout comment y remédier ?
    Ouvrir un tuto. et revoir les bases sur les listes?

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

  16. #16
    Membre averti
    Homme Profil pro
    geek
    Inscrit en
    Mai 2017
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : geek
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2017
    Messages : 44
    Par défaut
    Je ne comprends pas.
    r1 c'est une string, enfin je pense
    et je l' ajoute à une liste via un listep.append(r1).

    si je fais un print de r1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            if len(r1) == 1:
                print r1 # j'ai ça ['D53113050']
    r1 est considéré comme une liste ? soit ..

    j'ai essayé un r1=r1.replace("[","") guerre concluant
    puis un r1="".join(r1) bien mieux


    pourquoi r1 au début est envoyé dans une liste ?
    mon code est mal écrit ?
    ou c'est simplement normal pour le résultat issu d'un re.findall ?

  17. #17
    Membre très actif

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Billets dans le blog
    1
    Par défaut
    Salut.

    Ce n'est pas que r1 est considéré comme une liste, mais que c'est une liste. Le nom de la fonction re.findall est quand même assez explicite pour se dire qu'il pourrait y avoir plusieurs résultats renvoyés, donc un itérable contenant plusieurs châines de caractères.

    Et pour ajouter un itérable à une liste existante, cela se fait avec la méthode extend de list.

  18. #18
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 725
    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 725
    Par défaut
    Salut,

    Citation Envoyé par daniel-12 Voir le message
    pourquoi r1au début est envoyé dans une liste ?
    findall équivaut à "trouver tous les items" qui satisfont un ou des critères données... Et le résultat pourra être vide ou un ou plusieurs items. Et les "boîtes" de base permettant de stocker 0, 1 ou plus éléments sont listes et tuples.
    Et comme il s'agit de structures de bases, il faut apprendre à les utiliser.

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

Discussions similaires

  1. aide pour une regex
    Par casp13 dans le forum Langage
    Réponses: 3
    Dernier message: 21/02/2008, 09h41
  2. [RegEx] Besoin d'aide pour une regex
    Par vallica dans le forum Langage
    Réponses: 3
    Dernier message: 20/09/2006, 08h50
  3. [RegEx] Aide pour une regex
    Par pj69100 dans le forum Langage
    Réponses: 6
    Dernier message: 29/08/2006, 19h19
  4. [RegEx] Aide pour une REGEX svp
    Par Invité dans le forum Langage
    Réponses: 2
    Dernier message: 12/07/2006, 17h41
  5. [RegEx] Aide pour une REGEX
    Par Death83 dans le forum Langage
    Réponses: 6
    Dernier message: 28/06/2006, 15h50

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