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 :

RFC 3696 : la regex impossible pour la validation d'email ? [Python 3.X]


Sujet :

Python

  1. #1
    Membre émérite
    Avatar de Nothus
    Homme Profil pro
    aucun
    Inscrit en
    Juillet 2009
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : aucun
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2009
    Messages : 200
    Points : 2 427
    Points
    2 427
    Billets dans le blog
    27
    Par défaut RFC 3696 : la regex impossible pour la validation d'email ?
    Bonjour,

    Tout d'abord, voici ce que j'ai trouvé sur le forum (ça date un peu mais j'ai le même problème pratiquement au mot près) :
    https://www.developpez.net/forums/d561587/general-developpement/algorithme-mathematiques/general-algorithmique/validite-d-mail/

    Ma question est simple : quel est le meilleur moyen (pythonnique) pour parser un champ to (ou cc, cci) qui contient plusieurs adresse email valides au sens de la RFC 3696 ?

    Rappel de la RFC en question :
    https://tools.ietf.org/html/rfc3696

    La question est moins simple qu'il n'y paraît : des adresses peuvent être valident malgré leur peu d'usage "courant" sur le web... Exemples :
    • Abc\@def@example.com
    • Fred\ Bloggs@example.com
    • Joe.\\Blow@example.com
    • "Abc@def"@example.com
    • "Fred Bloggs"@example.com
    • (etc)


    ... Tous ses exemples sont bel et bien valides ! Avant qu'on me dise qu'une regEx est adaptée d'accord, mais je veux bien la comprendre avant de l'utiliser... celle proposée dans le post cité plus haut (cf utilisée par la RFC 5322) est imbitique voire limitée vis-à-vis de ce qui est possible :
    http://www.regular-expressions.info/email.html

    Et c'est fastidieux parce que les courriels sont séparés par des virgules dans les headers d'email avec, parfois !, des "<>" pour séparer du nom d'usage "humain". Résultat je patine gentillement dans la semoule à trouver un truc vraiment efficace et si possible, facile à maintenir. Si une bonne âme de la regex voulait bien m'éclairer (ou me propose une toute autre solution ?), ça m'avancerait beaucoup.

    Pour l'instant, je pensais à la validation, caractère par caractère, pour tenter de déterminer des groupes d'adresses, avant de les valider unitairement. Certes moins efficace mais pas nécessairement moins sûr. Qu'en pensez-vous ?

    Pour le contexte : une sorte d'IFTTT du SMTP où l'on peut envoyer des commandes vraiment pointues pour récupérer des ressources par courriel -> j'utilise toutes les possibilités offertes par les RFC.

    Bon après-midi à tous,

    Julien.
    "En dehors des langages de la famille LISP et du modèle RDF, point de salut."

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par Nothus Voir le message
    Ma question est simple : quel est le meilleur moyen (pythonnique) pour parser un champ to (ou cc, cci) qui contient plusieurs adresse email valides au sens de la RFC 3696 ?
    On regarde d'abord ce que sait faire le module email qui vient en standard avec Python puis on bricole intelligemment pour réduire ses limitations.

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

  3. #3
    Membre émérite
    Avatar de Nothus
    Homme Profil pro
    aucun
    Inscrit en
    Juillet 2009
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : aucun
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2009
    Messages : 200
    Points : 2 427
    Points
    2 427
    Billets dans le blog
    27
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    On regarde d'abord ce que sait faire le module email qui vient en standard avec Python puis on bricole intelligemment pour réduire ses limitations.
    Désolé je manque probablement d'intelligence mais je connais la fonction que tu évoques - et qui résout un point que l'on pourrait dire "annexe".

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    import email.utils
    addr = ("Abc\@def@example.com", "Fred\ Bloggs@example.com", "Joe.\\Blow@example.com", '"Abc@def"@example.com', '"Fred Bloggs"@example.com')
    for a in addr:
    	print(email.utils.parseaddr(a))

    Donnera bien un couple par item :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ('', 'Abc\\@def')
    ('', 'Fred\\ Bloggs@example.com')
    ('', 'Joe.\\Blow@example.com')
    ('', '"Abc@def"@example.com')
    ('', '"Fred Bloggs"@example.com')
    ... Mais le champ to ou cc ou cci a bien la difficulté qu'il faut d'abord trouver la paire qui doit être extraite de l'entête avant de passer à cette fonction. Et c'est là que le bât blesse (... si tu relis ma question).

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    addr2 = 'Abc\@def@example.com, Fred\ Bloggs@example.com, Joe.\\Blow@example.com, "Abc@def"@example.com, "Fred Bloggs"@example.com'
    print(email.utils.parseaddr(addr2)) 
    # renverra seulement ('', 'Abc\\@def') -- considérant l'explication Parse address – which should be the value of some address-containing field such as To or Cc

    Je ne me serais pas permis de poster pour si peu...

    Un split sur les virgules - vu que c'est le séparateur naturel pour les entêtes destinataires - n'a pas de sens, car les virgules peuvent être dans une adresse dans la partie local path sans que ça pose problème (avec ou sans échappement -> lorsqu'il y a simple ou double quote). Une regExp sur tous les possibles me semble bien monstrueuse.
    "En dehors des langages de la famille LISP et du modèle RDF, point de salut."

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Nothus Voir le message
    Un split sur les virgules - vu que c'est le séparateur naturel pour les entêtes destinataires - n'a pas de sens, car les virgules peuvent être dans une adresse dans la partie local path sans que ça pose problème (avec ou sans échappement -> lorsqu'il y a simple ou double quote).
    Donc d'une regexp monstrueuse, on est passé à écrire un code qui trouve les virgules en faisant attention à celles qui sont entre simple et double quote pour passer chaque récipient à email.utils.parseaddr
    nota avant de vous répondre, j'ai déjà trouvé un code sur Internet qui fait çà. Sans compter qu'il existe aussi d'autres packages qu'email qui font peut être déjà çà.

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

  5. #5
    Membre émérite
    Avatar de Nothus
    Homme Profil pro
    aucun
    Inscrit en
    Juillet 2009
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : aucun
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2009
    Messages : 200
    Points : 2 427
    Points
    2 427
    Billets dans le blog
    27
    Par défaut
    J'ai repris la source de la fonction que tu évoques : sur GitHub, elle sert d'une classe contenu dans le _parseaddr.py :
    https://github.com/python/cpython/bl.../_parseaddr.py

    Et là c'est intéressant car cette même fonction retourne le premier résultat trouvé... il suffit donc d'instancier la classe utilisée pour récupérer la liste complète :

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    import email._parseaddr
    o = email._parseaddr.AddressList('Abc\@def@example.com, Fred\ Bloggs@example.com, Joe.\\Blow@example.com, "Abc@def"@example.com, "Fred Bloggs"@example.com') 
    print(o.addresslist) 
    # retournera : [('', 'Abc\\@def'), ('', '@example.com'), ('', 'Fred\\ Bloggs@example.com'), ('', 'Joe.\\Blow@example.com'), ('', '"Abc@def"@example.com'), ('', '"Fred Bloggs"@example.com')]

    ... pas besoin ni de hack, ni de personnalisation. Dans Python tout est bon ! Dommage que la doc officielle n'en fasse pas davantage référence ni qu'elle soit dans les standards (au sens d'une classe référencée utilisable en l'état dans les docs). Car finalement elle accepte l'entête complet ou une portion (comme une adresse seule).

    Résolu ! Merci wiztricks.
    "En dehors des langages de la famille LISP et du modèle RDF, point de salut."

  6. #6
    Membre émérite
    Avatar de Nothus
    Homme Profil pro
    aucun
    Inscrit en
    Juillet 2009
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : aucun
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2009
    Messages : 200
    Points : 2 427
    Points
    2 427
    Billets dans le blog
    27
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Donc d'une regexp monstrueuse, on est passé à écrire un code qui trouve les virgules en faisant attention à celles qui sont entre simple et double quote pour passer chaque récipient à email.utils.parseaddr
    Dans l'absolu, si l'on reste sur une regExp qui se base en découpe sur les virgules, ça reste une regExp monstrueuse car ça ne limite pas vraiment tous les possibles... ?

    Au-delà de ta recherche (merci), je suis assez content, car la source de Python reprend pour ce point précis un parcours manuel de la chaîne de caractères de ce qui lui est fourni :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    def gotonext(self):
            """Skip white space and extract comments."""
            wslist = []
    while self.pos < len(self.field): (...)

    ... J'aurais peut-être réinventé la roue en le faisant, mais au moins j'étais sur la bonne piste...

    Bonne soirée.
    "En dehors des langages de la famille LISP et du modèle RDF, point de salut."

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

Discussions similaires

  1. [Article] Liste des balises et de leurs enfants pour une validation XHTML 1.1
    Par giminik dans le forum Publications (X)HTML et CSS
    Réponses: 12
    Dernier message: 12/02/2018, 15h11
  2. Regex pour une validation de password
    Par bougoud dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 19/09/2007, 14h54
  3. Connexion entrante impossible pour les serveurs de validation W3C
    Par Squalthor dans le forum Serveurs (Apache, IIS,...)
    Réponses: 30
    Dernier message: 13/10/2006, 17h10
  4. expresssions régulières pour la validation d'un mail
    Par ndj1983 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 03/02/2005, 13h54
  5. connexion impossible pour imprimante en réseau !!!
    Par Petogaz dans le forum Développement
    Réponses: 11
    Dernier message: 30/09/2004, 10h24

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