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 :

[regex] Exclusion d'une chaîne


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2019
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Nicaragua

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2019
    Messages : 68
    Points : 30
    Points
    30
    Par défaut [regex] Exclusion d'une chaîne
    Bonjour

    J'ai des notions de Python, mais je découvre les regex.
    Je crée un application qui utilisera des chaines de caractères pouvant prendre ces formes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    PayLoad
    PayLoad#x
    <xx>PayLoad
    <xxXXX>PayLoad
    <xx>PayLoad#x
    <xxXXX>PayLoad#x
    --> "PayLoad" peut être une phrase, un mot...
    --> "x", "xx" et "XXX" peuvent varier : ils forment un préfixe et un suffixe (facultatifs).

    Pour extraire "PayLoad" de cette chaine, en python :

    - Je repère l'absence de préfixe --> PayLoad commence à la lettre 0
    - Je repère la présence d'un préfixe court <xx> --> PayLoad commence à la lettre 4
    - Je repère la présence d'un préfixe long <xxXXX> --> PayLoad commence à la lettre 7
    - Je repère l'absence de suffixe --> PayLoad termine à la dernière lettre
    - Je repère la présence d'un suffixe #x --> PayLoad termine à la dernière lettre -2

    Ça fonctionne bien, mais avec pas mal de "if else"...

    Heureusement, j'ai découvert récemment les regex. J'ai eu l'intuition qu'elles pourraient m'aider à simplifier mon code.
    J'ai réussi assez facilement à sélectionner mes préfixes et suffixes :

    Profile de préfixe court <xx> :
    Profile de préfixe long <xxXXX> :
    Profile de suffixe #x :
    ou
    (Car, pour le moment, le suffixe ne peut être que "d" ou "e")

    J'arrive à sélectionner préfixe et suffixe en même temps :
    Cependant, impossible d'inverser la sélection... Apparemment, cette fonction n'existe pas...
    Impossible également de "tout sélectionner" puis d'exclure le préfixe et le suffixe...

    Ça m'a pris 15min pour comprendre comment sélectionner les balises, et ça fait des heures que je n'arrive pas à trouver un moyen de ne sélectionner que "PayLoad"...
    Pour le moment, je n'ai pas encore introduit les regex dans mon code, j'ai uniquement travaillé sur https://regexr.com/

    Est-ce qu'il serait possible d'extraire "Payload" de ma chaine de caractères uniquement en utilisant les regex ? Comment ?

    Merci à vous !

  2. #2
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2022
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 20
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2022
    Messages : 137
    Points : 284
    Points
    284
    Par défaut
    Bonjour,
    Une regex comme ceci semble faire l'affaire au vu de l'énoncé :
    ^(?:<.{2}>|<.{5}>)?(.*?)(?:#.$)?$

    Voici mes tests :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    import re
     
    # Exemple de chaînes de caractères
    strings = [
        "PayLoad",
        "PayLoad#d",
        "<xx>Pay1Load",
        "<xxXXX>PayL125oad",
        "<xx>PayLo6ad#d",
        "<xxXXX>Pay5Load#e"
    ]
     
    # Regex pour extraire "PayLoad"
    pattern = re.compile(r'^(?:<.{2}>|<.{5}>)?(.*?)(?:#.$)?$')
     
    # Fonction pour extraire "PayLoad"
    def extract_payload(string):
        match = pattern.match(string)
        if match:
            return match.group(1)
        return None
     
    # Tester la fonction sur les exemples
    for string in strings:
        payload = extract_payload(string)
        print(f"Original: {string} -> PayLoad: {payload}")
    Ca donne ceci :
    Original: PayLoad -> PayLoad: PayLoad
    Original: PayLoad#d -> PayLoad: PayLoad
    Original: <xx>Pay1Load -> PayLoad: Pay1Load
    Original: <xxXXX>PayL125oad -> PayLoad: PayL125oad
    Original: <xx>PayLo6ad#d -> PayLoad: PayLo6ad
    Original: <xxXXX>Pay5Load#e -> PayLoad: Pay5Load

    Cdt,

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 440
    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 440
    Points : 37 032
    Points
    37 032
    Par défaut
    Citation Envoyé par Yobeco Voir le message
    Est-ce que vous sauriez s'il serait possible d'extraire "Payload" de ma chaine de caractères uniquement en utilisant les regex ? Comment ?
    Votre phrase ne veut rien dire: vous vérifiez que "Payload" est présent pour récupérer ce qui est avant et après
    Ce qui s'écrit sans regexp::
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> lines
    ['PayLoad', 'PayLoad#x', '<xx>PayLoad', '<xxXXX>PayLoad', '<xx>PayLoad#x', '<xxXXX>PayLoad#x']
    >>> m = 'PayLoad'
    >>> s = lines[0]
    >>> i = s.find(m)
    >>> s[:i], s[i+len(m):]
    ('', '')
    >>> s = lines[4]
    >>> i = s.find(m)
    >>> s[:i], s[i+len(m):]
    ('<xx>', '#x')
    >>>
    La même chose avec re.search:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> re.search('PayLoad', lines[4])
    <re.Match object; span=(4, 11), match='PayLoad'>
    >>> re.search('PayLoad', lines[0])
    <re.Match object; span=(0, 7), match='PayLoad'>
    >>>
    Pour ce qui est de classifier préfixe et suffixe en fonction de leur longueur... ça se fera plus simplement "après".

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

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2019
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Nicaragua

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2019
    Messages : 68
    Points : 30
    Points
    30
    Par défaut
    [QUOTE=gabi7756;12048437]Bonjour,
    Une regex comme ceci semble faire l'affaire au vu de l'énoncé :
    ^(?:<.{2}>|<.{5}>)?(.*?)(?:#.$)?$
    [QUOTE]

    Merci pour ton aide :-)

    Ton code python fonctionne comme prévu. Il arrive à extraire Payload. :-)

    Nom : Capture d’écran du 2024-10-08 13-59-16.png
Affichages : 174
Taille : 33,6 Ko

    Pourquoi alors sur :
    https://regexr.com/
    toute la String est sélectionnée ?

    Nom : Capture d’écran du 2024-10-08 14-00-24.png
Affichages : 171
Taille : 20,9 Ko

    Le langage des regex n'est-il pas sensé être "universel" ? Ce site sert bien à essayer ses regex avant de les introduire dans son code, non ?
    Je vais devoir porter ce code en Kotlin également... Faut-il m’attendre à des surprises ?

    Je suis un peu perdu...

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2019
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Nicaragua

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2019
    Messages : 68
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Votre phrase ne veut rien dire
    Oui, désolé... C'est corrigé.

    Merci pour votre réponse.
    Je n'ai pas bien compris votre code. Il doit me manquer des notions... Je vais l'étudier plus à fond.

    Encore merci W :-)

  6. #6
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 905
    Points : 1 592
    Points
    1 592
    Billets dans le blog
    6
    Par défaut
    Bonjour.
    Citation Envoyé par Yobeco Voir le message

    Le langage des regex n'est-il pas sensé être "universel" ? Ce site sert bien à essayer ses regex avant de les introduire dans son code, non ?
    Je vais devoir porter ce code en Kotlin également... Faut-il m’attendre à des surprises ?

    Je suis un peu perdu...
    Une regex Perl s'écrit différemment qu'une regex JavaScript...
    Le module Re de python utilise une syntaxe proche d'une regex Perl. Donc pour tes essais sélectionne cette regex.
    Quant à Kotlin, des adaptations seront certainement nécessaires selon le type de regex utilisé.
    #Rien de nouveau sous le soleil, tout est vanité comme courir après le vent!
    Envie de développer pour Android avec Python? Pensez à Kivy
    Kivy c'est aussi ça: https://www.youtube.com/@MPython_Alaplancha

  7. #7
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2022
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 20
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2022
    Messages : 137
    Points : 284
    Points
    284
    Par défaut
    [QUOTE=Yobeco;12048553][QUOTE=gabi7756;12048437]Bonjour,
    Une regex comme ceci semble faire l'affaire au vu de l'énoncé :
    ^(?:<.{2}>|<.{5}>)?(.*?)(?:#.$)?$

    Merci pour ton aide :-)

    Ton code python fonctionne comme prévu. Il arrive à extraire Payload. :-)

    Nom : Capture d’écran du 2024-10-08 13-59-16.png
Affichages : 174
Taille : 33,6 Ko

    Pourquoi alors sur :
    https://regexr.com/
    toute la String est sélectionnée ?

    Nom : Capture d’écran du 2024-10-08 14-00-24.png
Affichages : 171
Taille : 20,9 Ko

    Le langage des regex n'est-il pas sensé être "universel" ? Ce site sert bien à essayer ses regex avant de les introduire dans son code, non ?
    Je vais devoir porter ce code en Kotlin également... Faut-il m’attendre à des surprises ?

    Je suis un peu perdu...


    Bjr,
    Dans le code python tu as du loupé ce truc :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    return match.group(1)
    Ca return le premier groupe capturant,

    Pour plus préciser :
    (?:<.{2}>|<.{5}>)? : Groupe non capturant optionnel qui correspond à une balise de 2 ou 5 caractères entre <>.
    (.*?) : Groupe capturant (groupe 1) qui correspond à n'importe quel caractère.
    (?:#.$)? : Groupe non capturant optionnel qui correspond à un caractère # suivi de n'importe quel caractère.


    Groupes de Capture :
    - match.group(0) : Retourne toute la chaîne correspondante.
    - match.group(1) : Retourne le contenu du premier groupe capturant, c'est-à-dire la partie entre les balises optionnelles et le suffixe optionnel.


    Cdt,

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 440
    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 440
    Points : 37 032
    Points
    37 032
    Par défaut
    Citation Envoyé par Yobeco Voir le message
    Le langage des regex n'est-il pas sensé être "universel" ?
    La page wikipedia sur les expressions régulières mentionne plusieurs standards... et le site mentionné précise bien son domaine de compatibilité: PCRE & JavaScript flavors of RegEx are supported.

    Citation Envoyé par Yobeco Voir le message
    Ce site sert bien à essayer ses regex avant de les introduire dans son code, non ?
    La partie du code que vous écrivez contenant des expressions régulières se teste et se met au point comme le reste, non?

    Citation Envoyé par Yobeco Voir le message
    Je n'ai pas bien compris votre code. Il doit me manquer des notions... Je vais l'étudier plus à fond.
    Je n'utilise que des fonctionnalités de bases du langage supposées être acquises avant de se lancer à coder...

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

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2019
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Nicaragua

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2019
    Messages : 68
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    La page wikipedia sur les expressions régulières mentionne plusieurs standards... et le site mentionné précise bien son domaine de compatibilité: PCRE & JavaScript flavors of RegEx are supported.

    - W
    Information très intéressante. Je suis parti sur des préjugés...

    J'ai trouvé un très bel article qui touche le sujet POSIX / PCRE et les bases du regex.
    https://buzut.net/la-puissance-des-regex/
    Si ça peut aider quelqu'un qui suivra ce Topic...

    J'utilise maintenant le site :
    https://regex101.com/

    J'aime un peu moins sa coloration syntaxique, mais il est plus facile de choisir la norme et le langage de contexte.
    Je reviens dès que j'ai eu le temps d'expérimenter tout ça plus attentivement.

    Merci encore :-)

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2019
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Nicaragua

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2019
    Messages : 68
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par gabi7756 Voir le message
    Bjr,
    Dans le code python tu as du loupé ce truc :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    return match.group(1)
    Ca return le premier groupe capturant,

    Pour plus préciser :
    (?:<.{2}>|<.{5}>)? : Groupe non capturant optionnel qui correspond à une balise de 2 ou 5 caractères entre <>.
    (.*?) : Groupe capturant (groupe 1) qui correspond à n'importe quel caractère.
    (?:#.$)? : Groupe non capturant optionnel qui correspond à un caractère # suivi de n'importe quel caractère.

    Groupes de Capture :
    - match.group(0) : Retourne toute la chaîne correspondante.
    - match.group(1) : Retourne le contenu du premier groupe capturant, c'est-à-dire la partie entre les balises optionnelles et le suffixe optionnel.

    Cdt,
    Merci pour ces précisions. :-)
    Cependant, j'ai utilisé un copier / coller de ton code. Comment peux-tu voir qu'une ligne manque ?

    Je vais regarder ça de près.

  11. #11
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2022
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 20
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2022
    Messages : 137
    Points : 284
    Points
    284
    Par défaut
    Citation Envoyé par Yobeco Voir le message
    Merci pour ces précisions. :-)
    Cependant, j'ai utilisé un copier / coller de ton code. Comment peux-tu voir qu'une ligne manque ?

    Je vais regarder ça de près.

    "Tu as loupé ca " C'était pour dire que t'avais pas recherché la signification du return match.group(1)

    Le code était complet et fonctionnel pour la demande évoqué lol
    Peut être en poussant la recherche tu serais tombé sur les groupes capturant ou non , dans ce sens la

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2019
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Nicaragua

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2019
    Messages : 68
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par gabi7756 Voir le message
    "Tu as loupé ca " C'était pour dire que t'avais pas recherché la signification du return match.group(1)

    Le code était complet et fonctionnel pour la demande évoqué lol
    Peut être en poussant la recherche tu serais tombé sur les groupes capturant ou non , dans ce sens la
    Ok ok :-)

    Merci

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2019
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Nicaragua

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2019
    Messages : 68
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par gabi7756 Voir le message
    Bonjour,
    Une regex comme ceci semble faire l'affaire au vu de l'énoncé :
    ^(?:<.{2}>|<.{5}>)?(.*?)(?:#.$)?$

    Voici mes tests :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    import re
     
    # Exemple de chaînes de caractères
    strings = [
        "PayLoad",
        "PayLoad#d",
        "<xx>Pay1Load",
        "<xxXXX>PayL125oad",
        "<xx>PayLo6ad#d",
        "<xxXXX>Pay5Load#e"
    ]
     
    # Regex pour extraire "PayLoad"
    pattern = re.compile(r'^(?:<.{2}>|<.{5}>)?(.*?)(?:#.$)?$')
     
    # Fonction pour extraire "PayLoad"
    def extract_payload(string):
        match = pattern.match(string)
        if match:
            return match.group(1)
        return None
     
    # Tester la fonction sur les exemples
    for string in strings:
        payload = extract_payload(string)
        print(f"Original: {string} -> PayLoad: {payload}")
    Ca donne ceci :
    Original: PayLoad -> PayLoad: PayLoad
    Original: PayLoad#d -> PayLoad: PayLoad
    Original: <xx>Pay1Load -> PayLoad: Pay1Load
    Original: <xxXXX>PayL125oad -> PayLoad: PayL125oad
    Original: <xx>PayLo6ad#d -> PayLoad: PayLo6ad
    Original: <xxXXX>Pay5Load#e -> PayLoad: Pay5Load

    Cdt,

    J'ai étudié plus à fond ton code. J'ai appris beaucoup de choses ! :-)

    - Je l'ai étendu à d'autres préfixe que j'ai implémentés.
    - J'ai testé avec d'autres caractères UTF8 que mon application sera susceptible de rencontrer.

    Code : 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    import re
     
    # Exemple de chaînes de caractères à traiter
    strings = [
        "Bonjour tout le monde !",
        "안녕하세요, 여러분!#d",
        "<xx>Γεια σε όλους!",
        "<xxXXX>Привет всем!",
        "<xx>صباح الخير على الموضة!#d",
        "<xxXXX>你好,一切正常#e",
        "-bm-A",
        "*fr*AVION",
        "/gd/oi56hs6rmd59aq55df4fs477"
    ]
     
    # Regex pour extraire "PayLoad"
    # "pattern" est un objet optimisé qui peut être réutilisé plusieurs fois. (facultatif)
    pattern = re.compile(r'^(?:<.{2}>|<.{5}>|-.{2}-|\*.{2}\*|/.{2}/)?(.*?)(?:#.)?$')
     
    # Fonction pour extraire "PayLoad"
    def extract_payload(string):
        match = pattern.search(string)  # re.match() : Vérifie uniquement si la chaîne commence par une correspondance de l'expression régulière.
                                        # re.search() : Cherche une correspondance n'importe où dans la chaîne.
        if match:
            return match.group(1)
        return None
     
    # Tester la fonction sur les exemples
    for string in strings:
        payload = extract_payload(string)
        print(f"Original: {string} -> PayLoad: {payload}")
    J'ai eu l'impression que le 1er "$" que tu avais laissé dans :
    N'était pas nécessaire, puisqu'il était aussi spécifié à la fin de l'expression régulière qu'il devait s'agir du dernier pattern.
    Je l'ai enlevé et ça fonctionne toujours bien.
    pattern = re.compile(r'^(?:<.{2}>|<.{5}>|-.{2}-|\*.{2}\*|/.{2}/)?(.*?)(?:#.$)?$')
    pattern = re.compile(r'^(?:<.{2}>|<.{5}>|-.{2}-|\*.{2}\*|/.{2}/)?(.*?)(?:#.)?$')
    Ai-je fait une bêtise ?

    Il m'a aussi semblé que, parce qu'il n'y a qu'un seul groupe à traiter, je pourrais utiliser :
    au lieu de :
    Y avait-il une raison particulière pour laquelle tu avais préféré pattern.match() ?

    Merci en tous cas. :-)

    Tout est beaucoup plus clair

  14. #14
    Membre actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2022
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 20
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2022
    Messages : 137
    Points : 284
    Points
    284
    Par défaut
    Citation Envoyé par Yobeco Voir le message
    J'ai étudié plus à fond ton code. J'ai appris beaucoup de choses ! :-)

    - Je l'ai étendu à d'autres préfixe que j'ai implémentés.
    - J'ai testé avec d'autres caractères UTF8 que mon application sera susceptible de rencontrer.

    Code : 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    import re
     
    # Exemple de chaînes de caractères à traiter
    strings = [
        "Bonjour tout le monde !",
        "안녕하세요, 여러분!#d",
        "<xx>Γεια σε όλους!",
        "<xxXXX>Привет всем!",
        "<xx>صباح الخير على الموضة!#d",
        "<xxXXX>你好,一切正常#e",
        "-bm-A",
        "*fr*AVION",
        "/gd/oi56hs6rmd59aq55df4fs477"
    ]
     
    # Regex pour extraire "PayLoad"
    # "pattern" est un objet optimisé qui peut être réutilisé plusieurs fois. (facultatif)
    pattern = re.compile(r'^(?:<.{2}>|<.{5}>|-.{2}-|\*.{2}\*|/.{2}/)?(.*?)(?:#.)?$')
     
    # Fonction pour extraire "PayLoad"
    def extract_payload(string):
        match = pattern.search(string)  # re.match() : Vérifie uniquement si la chaîne commence par une correspondance de l'expression régulière.
                                        # re.search() : Cherche une correspondance n'importe où dans la chaîne.
        if match:
            return match.group(1)
        return None
     
    # Tester la fonction sur les exemples
    for string in strings:
        payload = extract_payload(string)
        print(f"Original: {string} -> PayLoad: {payload}")
    J'ai eu l'impression que le 1er "$" que tu avais laissé dans :
    N'était pas nécessaire, puisqu'il était aussi spécifié à la fin de l'expression régulière qu'il devait s'agir du dernier pattern.
    Je l'ai enlevé et ça fonctionne toujours bien.


    Ai-je fait une bêtise ?

    Il m'a aussi semblé que, parce qu'il n'y a qu'un seul groupe à traiter, je pourrais utiliser :
    au lieu de :
    Y avait-il une raison particulière pour laquelle tu avais préféré pattern.match() ?

    Merci en tous cas. :-)

    Tout est beaucoup plus clair
    Bjr,
    Tu as probablement pas fait de bêtise tant que ca fonctionne lol
    La bêtise m'incombe parce que c'est inutile effectivement.


    Pour ce qui est du pattern.match, pas forcément de raison particulière ,j'avais l'habitude de l'utiliser. Après à dire que c'est mieux ou pire que le search , aucune idée et j'ai pas forcément chercher.
    A défaut de savoir si on peux récupéré plusieurs groupe avec le search jme dis autant utiliser le group tout le temps.
    A tort ou à raison

    Cdt,

  15. #15
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 939
    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 : 3 939
    Points : 7 348
    Points
    7 348
    Par défaut
    Bonjour,

    J'ai pas suivi la discussion, mais je vais ajouter deux précisions,
    1. En terme de performance les deux fonctions sont équivalentes
    2. Elles sont utilisées pour des cas d'utilisations différents (voir la doc)


    Donc le choix de l'une ou l'autre dépend du contexte de l'application.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  16. #16
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 911
    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 911
    Points : 6 704
    Points
    6 704
    Par défaut
    À propos de la function à utiliser, le module re t'en propose 3:
    • re.match qui cherche une correspondance de la pattern commençant au début de la chaîne.
    • re.search qui cherche la première correspondance n'importe où dans la chaîne.
    • re.fullmatch qui cherche une correspondance de la pattern commençant au début de la chaîne et finissant à la fin de la chaîne


    Ta pattern décrit toute la chaîne du début à la fin, d'après toi quelle est la méthode à utiliser?
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  17. #17
    Nouveau membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2019
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Nicaragua

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2019
    Messages : 68
    Points : 30
    Points
    30
    Par défaut
    Apparemment, dans mon cas, re.fullmatch() pourrait être adapté également puis qu'il n'y a qu'un groupe et que par définition, il doit justement contenir PayLoad...

    J'ai fait un test : ça fonctionne également.

    Merci pour tout :-)

  18. #18
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 911
    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 911
    Points : 6 704
    Points
    6 704
    Par défaut
    Oui c'est bien ça, mais ça n'a rien à voir avec le nombre de groupes, ça tient juste au fait que la pattern décrit la chaîne en entier et pas juste une partie de la chaîne. Le groupe de capture sert juste à isoler une partie de la correspondance et à la rendre disponible dans l'objet Match retourné par l'une de ces fonctions.

    L'intérêt de re.fullmatch (et de re.match), par rapport à re.search réside dans le fait que si la pattern échoue au début de la chaîne, elle ne sera pas retentée plus loin dans celle-ci. Autrement dit, elle échoue plus vite.

    Quelques remarques:
    • Si tu utilises re.fullmatch, tu peux enlever les ancres ^ et $ de la pattern puisque celle-ci deviennent implicites de par le choix de cette fonction.
    • Le coté "condensat hermétique" des patterns n'est pas une fatalité, celle-ci peuvent être espacées, indentées, commentées, et les groupes de capture peuvent-être nommés (au lieu d'être juste numérotés):
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      pattern = re.compile(r'''
          # préfixe
          (?:
              < .{2} (?:.{3})? >
            |
              (?P<Delimiter> [-*/] ) .{2} (?P=Delimiter)
          )?
       
          # payload
          (?P<Payload> [^#]* )
       
          # suffixe
          (?: \# [de] )?
         ''', re.X)
      On peut alors accéder à la capture par son nom: match.group('Payload') dans le code python, mais aussi dans la pattern elle-même en se référent à une capture précédente comme avec (?P=Delimiter).
    • Choisir entre re.search, re.match, re.fullmatch, lorsqu'on a une pattern décrivant une chaîne complète n'est pas une question de vie ou de mort et n'impactera pas les performances tant que les chaînes étudiées sont courtes. Par contre faire le choix entre l'une des trois dénote une intention claire qui facilite la lecture du code.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  19. #19
    Nouveau membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Août 2019
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Nicaragua

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2019
    Messages : 68
    Points : 30
    Points
    30
    Par défaut [Résolu] Code final
    Le coté "condensat hermétique" des patterns n'est pas une fatalité, celle-ci peuvent être espacées, indentées, commentées, et les groupes de capture peuvent-être nommés (au lieu d'être juste numérotés):
    Super intéressant !

    Merci pour ces informations !
    Je vais étudier comment mieux structurer mes schémas regex. J'ai beaucoup à apprendre !

    Pour terminer ce fil, voici le code fonctionnel que j'utilise maintenant dans mon application (et qui remplace un bon nombre de if / else imbriqués...) :

    Code : 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    # Schémas regex pour cibler les préfixes / payload / suffixes
    payload_pattern = re.compile(r'^(?:<.{2}>|<.{5}>|-.{2}-|\*.{2}\*|/.{2}/)?(.*?)(?:#.)?$')
    prefixe_pattern = re.compile(r'^(<.{2}>|<.{5}>|-.{2}-|\*.{2}\*|/.{2}/)?')
    suffixe_pattern = re.compile(r'(#.)?$')
     
    # Classe qui analysera le contenu du code QR et extraira les 3 parties
    class Mael_analyze:
        def __init__(self, qr_content):
            self.qr_content = qr_content
     
        # Méthodes qui contiennent la logique pour créer directement les propriétés
        @property
        def prefixe(self):
            match = prefixe_pattern.match(self.qr_content)
            if match:
                return match.group()
     
        @property
        def payload(self):
            match = payload_pattern.fullmatch(self.qr_content)
            if match:
                return match.group(1)
     
        @property
        def suffixe(self):
            match = suffixe_pattern.search(self.qr_content)
            if match:
                return match.group()
    C'est un objet dont les méthodes (utilisant les regex), grâce au décorateur "@property", calculent et créer directement les propriétés de l'objet en fonction de qr_content.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    # Instanciation de la classe avec le texte contenu dans un code QR
    scan1 = Mael_analyze(text)
     
    # Lancement des fonctions de son et d'affichage
    mael_proces(scan1.prefixe, scan1.payload, scan1.suffixe)
    J'utilise donc, dans une autre fonction, ces 3 éléments pour en faire ce qu'il faut...

    Merci à tous !

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

Discussions similaires

  1. [Regex] Comment tester une chaîne ASCII 7bits ?
    Par Raduris dans le forum Framework .NET
    Réponses: 4
    Dernier message: 27/03/2006, 10h42
  2. [Regex] Remplacement d'une chaîne avec $
    Par TSnarfK dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 27/01/2006, 11h44
  3. [Regex]Match d'une regexp avec une chaîne avec caractères spéciaux
    Par gdawirs dans le forum Collection et Stream
    Réponses: 13
    Dernier message: 25/11/2005, 13h24
  4. [Random] exclusion d'une valeur
    Par lanfeustdetroll dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 04/10/2005, 14h29
  5. [Regex] Vérifier qu'une chaîne respecte une expression régulière
    Par PeteMitchell dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 13/05/2004, 15h22

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