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 :

Expression régulière et enlever un groupe [Python 3.X]


Sujet :

Python

  1. #1
    bm
    bm est déconnecté
    Membre confirmé

    Homme Profil pro
    Freelance
    Inscrit en
    Octobre 2002
    Messages
    874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Freelance
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2002
    Messages : 874
    Points : 556
    Points
    556
    Billets dans le blog
    6
    Par défaut Expression régulière et enlever un groupe
    Bonjour,

    <div id='p1'><u>Mercredi 22 Février 2017 :</u></div>
    Début 2015 était plus froid que début 2017.<br>
    Je veux sélectionner que les lignes avec 201x et ne pas tenir compte de la ligne avec </div>.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for t in fic:
        if re.search(r"201[5-8](?!(</div>))", t) is not None :
            print(t)
    Cette exclusion de donne rien avec re.search

    @+

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par bm Voir le message
    Je veux sélectionner que les lignes avec 201x et ne pas tenir compte de la ligne avec </div>.
    Bonjour

    Je ne suis pas expert des regex donc si je devais faire ça, je commencerais par
    1. exclure les lignes contenant "</div>"
    2. ne prendre de ce qui reste que les lignes contenant "201X"

    Et donc utiliser une regex dédiée à chaque action...
    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]

  3. #3
    bm
    bm est déconnecté
    Membre confirmé

    Homme Profil pro
    Freelance
    Inscrit en
    Octobre 2002
    Messages
    874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Freelance
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2002
    Messages : 874
    Points : 556
    Points
    556
    Billets dans le blog
    6
    Par défaut
    En cherchant un peu c'est basique :

    Par exemple, Isaac (?!Asimov) correspondra à la chaîne 'Isaac' seulement si elle n’est pas suivie par 'Asimov'.
    [Résolu]

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par bm Voir le message
    Par exemple, Isaac (?!Asimov) correspondra à la chaîne 'Isaac' seulement si elle n’est pas suivie par 'Asimov'.
    Alors il se trouve que je ne suis tout de même pas resté à rien faire suite à ton topic. J'ai donc moi aussi hier lu cette doc et moi aussi vu cet exemple (d'autant plus que j'adore les livres d'Isaac Asimov que j'ai tous donc il m'a sauté aux yeux). Puis ai tenté de l'appliquer mais n'ai pas réussi.
    Les exemples que j'ai tentés
    • print(re.search(r"(?!123)", "to123to")) en me disant que je cherchais quelque chose qui ne contiendrait pas "123"
    • print(re.search(r".{0,}(?!123)", "to123to")) en me disant que je cherchais n'importe quelle suite de caractères mais qui ne serait pas suivie de "123"

    et dans les deux cas n'ai pas réussi (mais comme je l'avais dit je ne suis pas expert des regex)

    Citation Envoyé par bm Voir le message
    En cherchant un peu c'est basique
    Ben t'aurais cherché dès le départ tu n'aurais pas eu besoin de venir ici demander de l'aide. Accessoirement il est tout de même d'usage assez courant que quand on est venu demander de l'aide sur un forum et qu'on finit par trouver (soit parce que l'aide a été utile, soit qu'on ait trouvé tout seul) qu'on montre la solution. C'est un minimum de politesse vis à vis de ceux qui se sont intéressés à ton problème.
    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]

  5. #5
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    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 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    print(re.search(r"(?!123)", "to123to")) en me disant que je cherchais quelque chose qui ne contiendrait pas "123"
    (?!123) est une assertion comme ^ ou \b qui ne consomme aucun caractère, ce qui fait que la pattern réussit dés le début de la chaîne (puisque cette position est suivie par "to123to" et donc pas par "123") mais la correspondance est la chaîne vide.

    print(re.search(r".{0,}(?!123)", "to123to")) en me disant que je cherchais n'importe quelle suite de caractères mais qui ne serait pas suivie de "123"
    Oui et c'est précisément ce qui est renvoyé. Au début de la chaîne, .{0,} consomme tous les caractères jusqu'à la fin de la ligne (car les quantificateurs sont gourmands par défaut) et à la fin de la ligne, donc après "to123to", il n'y a pas "123", il n'y a rien. Comme dans le cas précédent la pattern réussit dés le début de la chaîne mais renvoie toute la chaîne.
    Pour trouver tous les bouts de chaîne qui ne soient pas immédiatement suivis par "123", il faudrait contrôler les caractères un par un et écrire:(?:.(?!123))+.

    Pour trouver une chaîne sur une ligne n'en contenant pas une autre, on peut ancrer le test avant au début de la chaîne, mais en laissant à la sous-pattern qu'il contient le loisir de parcourir toute la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> print(re.search(r"^(?!.*123).*(to)", "to123to"))
    None
    >>> print(re.search(r"^(?!.*13).*(to)", "to123to"))
    <_sre.SRE_Match object; span=(0, 7), match='to123to'>
    >>> print(re.search(r"^(?!.*13).*(to)", "to123to").group(1))
    to
    >>> print(re.search(r"^(?!.*13).*?(to)", "to123to"))
    <_sre.SRE_Match object; span=(0, 2), match='to'>
    >>> print(re.search(r"^(?!.*13).*?(to)", "to123to").group(1))
    to
    Mais le problème avec cette méthode, c'est qu'il n'est pas possible d'obtenir toutes les occurrences de "to" avec re.findall ou re.finditer car l'ancre ^ échouera dés la 2e tentative (on obtient ['to'] et pas ['to', 'to']) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> print(re.findall(r"^(?!.*13).*?(to)", "to123to"))
    ['to']
    Il n'y a à actuellement aucun moyen de trouver toutes les occurrences (dont on ne connaît pas le nombre à l'avance) d'une chaîne n'en contenant pas une autre avec le module re. (Sauf si on sait à l'avance que ce qu'on recherche est toujours avant la chaîne interdite; dans ce cas il suffit d'écrire to(?!.*123) ou \b201[5-8]\b(?!.*</div>))
    Donc le plus simple reste à faire un if '123' not in s: au préalable, ou d'utiliser une autre regex si la partie interdite est plus complexe.

    Ou alors, il faut se tourner vers le module pypi/regex qui lui a toutes les fonctionnalités dont on puisse rêver et qui permettent de faire ça, dont:
    • les tests arrière de taille variable: (?<!123.*)to(?!.*123)
    • l'ancre \G pour forcer les correspondances à être contiguë: \G(?:(?!123).)*(to)(?!.*123)
    • les verbes de contrôle du backtracking: ^.*123.*(*SKIP)(*F)|to (la première alternative consomme toute la chaîne, (*F) force l'échec, et (*SKIP) marque la position à partir de laquelle le moteur de regex peut faire une autre tentative (mais comme c'est la fin de la chaîne...)
    • les captures répétées: ^(?!.*123)(?:.*?(to))+ (avec re chaque répétition de la capture écrase la précédente, là elles sont stockées).
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Magnifique explications. Toi on voit que tu es un expert des regex

    Le seul détail c'est que tu t'es focalisé sur mon exemple "to123to" alors que moi j'avais monté cet exemple juste pour essayer de trouver comment utiliser la solution "(?!xxx)" pour ensuite l'appliquer au sujet initial de ce topic c'est à dire les lignes contenant "201X" et ne contenant pas "</div>".

    Bon bref tes explications m'ont enchantées et je les ai lues plusieurs fois... mais ne résolvent pas le pb initial

    Citation Envoyé par CosmoKnacki Voir le message
    Citation Envoyé par Sve@r Voir le message
    ...donc si je devais faire ça, je commencerais par
    1. exclure les lignes contenant "</div>"...
    Donc le plus simple reste à faire un if '123' not in s: au préalable
    Et là on retombe sur ma première préconisation
    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]

  7. #7
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    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 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Merci.

    Le seul détail c'est que tu t'es focalisé sur mon exemple "to123to" alors que moi j'avais monté cet exemple juste pour essayer de trouver comment utiliser la solution "(?!xxx)" pour ensuite l'appliquer au sujet initial de ce topic c'est à dire les lignes contenant "201X" et ne contenant pas "</div>".

    Bon bref tes explications m'ont enchantées et je les ai lues plusieurs fois... mais ne résolvent pas le pb initial
    Oui c'est vrai, alors pour résumer:
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  8. #8
    bm
    bm est déconnecté
    Membre confirmé

    Homme Profil pro
    Freelance
    Inscrit en
    Octobre 2002
    Messages
    874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Freelance
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2002
    Messages : 874
    Points : 556
    Points
    556
    Billets dans le blog
    6
    Par défaut
    <div id='p1'><u>Mercredi 22 Février 2017 :</u></div>
    Début 2015 était plus froid que début 2017.<br>
    Je veux 2017 , mais en excluant que ce qui vient après n'est pas :</u
    Mais il faut continuer pour exclure d'autres cas
    Automatiser ce filtrage est un vaste espace
    La solution générale est du domaine de l'expert


  9. #9
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    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 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Le problème est que tu cherches à résoudre par des manipulations de chaînes un problème qui relève du parsing html; car éviter qu'une partie de texte ne soit prise en compte lorsqu'elle se trouve entre certaines balises est beaucoup plus simple avec un parser html supportant XPath (ou éventuellement les sélecteurs css).

    En fait si tu pouvais montrer un peu plus de ton document html (voire le document en entier), histoire qu'on puisse se faire une idée de sa structure, et expliquer à partir de cette structure les parties que tu cherches à éviter, je pense que la ou les solutions proposées seraient bien plus simple. Si tu galères autant c'est le message clair que les regex ne sont pas adaptées.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    • sinon
    J'étais effectivement parti à essayer de résoudre ce cas (le plus général) en utilisant uniquement les regex.

    Citation Envoyé par CosmoKnacki Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if '</div>' not in s:
        results = re.findall(r'\b201[5-8]\b', s)
    Ok, là j'y arrivais aussi


    Citation Envoyé par bm Voir le message
    Citation Envoyé par bm Voir le message
    En cherchant un peu c'est basique :
    [Résolu]
    Automatiser ce filtrage est un vaste espace
    La solution générale est du domaine de l'expert
    Mouais. Facile de venir faire le barbot avec ses "oh il suffisait de chercher" comme si les autres ne cherchaient pas (ou mal) alors qu'en réalité rien n'est résolu et que nos (mes) recherches n'étaient donc pas si inefficaces que ça.
    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
    bm
    bm est déconnecté
    Membre confirmé

    Homme Profil pro
    Freelance
    Inscrit en
    Octobre 2002
    Messages
    874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Freelance
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2002
    Messages : 874
    Points : 556
    Points
    556
    Billets dans le blog
    6
    Par défaut
    <div id='p1'><u>Mercredi 22 Février 2017 :</u></div>
    Je veux compter les titres et les classer en année.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        exp1 = r"201[5-8] :</u"
        exp2 = r"201[5-8](?! :</u)(?!</option>)"
    exp1 sort les titres(59) , exp2 sort les années (53) qui ne sont pas dans les titres et dans un menu option

    Ajouter d'autres filtrage avec exp2 dépend des balises html et de la rédaction du document

    nb : il n'y a pas de bdd alors avec une pleine page Jquery , import re de python est bien suffisant

  12. #12
    bm
    bm est déconnecté
    Membre confirmé

    Homme Profil pro
    Freelance
    Inscrit en
    Octobre 2002
    Messages
    874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Freelance
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2002
    Messages : 874
    Points : 556
    Points
    556
    Billets dans le blog
    6
    Par défaut

    Si il fallait compter des occurences dans un document pdf, quelle méthode utiliser
    pour ouvrir le pdf et sortir le texte avec python ?


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

Discussions similaires

  1. Réponses: 1
    Dernier message: 23/06/2011, 18h34
  2. extraction de groupe d'une expression régulière
    Par TaymouWan dans le forum C#
    Réponses: 9
    Dernier message: 22/05/2009, 18h09
  3. extraction des groupe des expression régulières
    Par TaymouWan dans le forum C#
    Réponses: 4
    Dernier message: 22/05/2009, 12h27
  4. Expressions régulières et groupes capturants
    Par ®om dans le forum Langage
    Réponses: 1
    Dernier message: 09/01/2008, 15h37
  5. [Regex] Expressions régulières: sous groupe
    Par debdev dans le forum Collection et Stream
    Réponses: 12
    Dernier message: 07/07/2005, 14h10

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