trouver des adresses courriels

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
YvesRossignol
Messages : 133
Inscription : lun. 28/mars/2016 19:09

trouver des adresses courriels

Message par YvesRossignol »

Bonjour, je voudrais trouver des adresses courriels dans le texte d'un courriel. Je pense le transformer en txt puis ensuite recherche "mailto:" ou "[" et "]", j'ai beau chercher mais je ne comprends pas comment faire avec des commandes du genre stringfields car je vais trouver uniquement une position et nom pas la chaîne... Je voudrais écrire ensuite un fichier txt ou csv... mais ca je pense être capable de le faire. Je sais que j'ai vu des messages la-dessus mais je ne les retrouve pas.

Merci de me dire quel commande prendre. J'ai passé la librairie string au complet fonction par fonction mais j'ai pas trouvé.

Yves
Yves Rossignol
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: trouver des adresses courriels

Message par Kwai chang caine »

Bonjour,

Je suis sur smartphone, donc pas possible de te donner un code

Je pense qu'un champion des regex comme Marco pourrait te pondre ça en une seconde, c'est la meilleure solution, mais la plus incompréhensible :lol:

Une idée serait d'utiliser stringfield dans une boucle, à la recherche des espaces.
Cette fonction va donc te découper ta phrase en mots, puisque en principe chaque mot est séparé par un espace.
Et pour chacun des mots que tu remontes, tu test si dedans il y a un arobase, avec findstring()

Comme une adresse mail est comme un lien, elle ne peut contenir d'espace, et bien si il y a un arobase ce devrait être une adresse.
A part si il y a une faute dans le texte et qu'un mot est collé à ton adresse, mais bon on ne peux que difficilement gérer ce genre de chose

Une autre méthode, rechercher avec findstring l'arobase puis remonter et lire chaque caractère en partant de la position avec un mid de 1 lettre, jusqu'à trouver un espace, et pareil dans l'autre sens

Ou 3e solution, chercher larobase comme au dessus et réutiliser findstring pour chercher un espace avec findstring en partant de la position de larobase trouvé, et pour lespace d'avant, en cherchant les espaces et s'arrêter quand la pos est supérieur à larobase, en prenant la pos précèdente.

En fait ya noir de méthodes. Chacun choisissant la sienne
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Marc56
Messages : 2198
Inscription : sam. 08/févr./2014 15:19

Re: trouver des adresses courriels

Message par Marc56 »

Une adresse mail n'est pas forcément entourée par un espace, elle peut l'être par "<" ">" ou même précédée par ":" si elle est dans un lien mailto. Sans oublier qu'elle peut être au début ou en fin de ligne.

Avec les fonctions chaîne, il faut chercher l'@ puis prendre
=== à gauche
Les lettres (en tenant compte des majuscules et minuscules bien qu'elles soient ignorées)
Les chiffres
. (mais pas plusieurs à la suite)
_
%
+
-
=== puis
@
=== et à droite
Les lettres
Les chiffres
.
-
=== une ou plusieurs fois
=== .
Les lettres
au moins 2
Bon courage :P

Ou alors une ligne d'expression régulière

Code : Tout sélectionner

If OpenFile(0, "FichierSource.txt")
     While Not Eof(0)
          Full_Text$ + ReadString(0) + #CRLF$
     Wend 
     CloseFile(0)
Else
     End
EndIf

RegEx$ = "\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b"

If CreateRegularExpression(1, RegEx$, #PB_RegularExpression_NoCase)
     If ExamineRegularExpression(1, Full_Text$)
          While NextRegularExpressionMatch(1)
               Debug RegularExpressionMatchString(1)
          Wend 
     EndIf
EndIf
L'expression n'est pas complètement au point car elle permet plusieurs points consécutif.

:wink:
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: trouver des adresses courriels

Message par Ar-S »

Yop,
Extrait d'un code de Luis qui fonctionne très bien.
J'ai ajouté qques tests et ça marche bien.

Code : Tout sélectionner

    Procedure.i RegExMatch (text$, regex$ = "")
    ; [DESC]
    ; Verify if a regular expression match with the passed string.
    ;
    ; [INPUT]
    ; text$ : The string to be checked.
    ; regex$ : The regular expression to be used.
    ;    
    ; [RETURN]
    ; 1 if there is a match, 0 if not, -1 if the regular expression is invalid.
    ;
    ; [NOTES]
    ; You can omit the regular expression between multiple calls it the regex doesn't change.
    ;
    ; Here is a list of some of the more useful commands for pattern matching and rember:
    ; the regex engine is eager, and ?, *, +, are greedy
    ;
    ; ^     = look at the start of the line (if used at the begin of the expression)
    ; $     = look at the end of the line
    ; \A    = look at the start of the string
    ; \Z    = look at the end of the string
    ; |     = OR
    ; ^     = NOT (if not at the begin)
    ;
    ; .     = any char that is not a newline (equivalent to [^\r\n] under Windows)
    ; ?     = the preceding char/token is optional (also used to switch from greedy to lazy, ie: *?)
    ;\s     = any whitespace such as [ \t\r\n]
    ;\S     = anything that is not a whitespace
    ;\d     = any decimal digit [0-9]
    ;\D     = anything that is not a decimal digit
    ;\w     = any "word" character [A-Za-z0-9_]
    ;\W     = anything that is not a "word" character
    ;\b     = a boundary between a word and a non-word
    ;\B     = no boundary between word characters
    ;\Q \E  = interpret all the characters between the \Q and the \E are as literal characters
    ;
    ; *     = 0 or many times  {0,}
    ; +     = 1 or many times  {1,} (also used to switch from greedy to possessive, ie: *+)
    ; (     = start sub expression
    ; )     = end sub expression
    ; {n}   = repeated n times
    ; {n,m} = repeated n times min, but no more than m
    ; {n,}  = repeated n times min, unlimited max
    ; [     = start char specifier
    ; ]     = end char specifier
    ; (?i)  = case insensitive matching
    ; (?-i) = case sensitive matching
    ;
    ; ?:    = turn off capturing
    ; ?!    = negative lookahed, usually to match something not followed by something else
    ;         example: a(?!b) = a not followed by b
    ;
    ; \     = the escape character
    ; \e    = escape ($1B)
    ; \n    = newline ($0A)
    ; \r    = carriage return ($0D)
    ; \t    = tab ($09)
    ; \xhh  = character with hex code hh
    ;
    ; Character classes, for example: [[:alpha:]]
    ;
    ; alnum    letters and digits
    ; alpha    letters
    ; ascii    character codes 0 - 127
    ; blank    space or tab only
    ; cntrl    control characters
    ; digit    decimal digits (same as \d)
    ; graph    printing characters, excluding space
    ; lower    lower case letters
    ; print    printing characters, including space
    ; punct    printing characters, excluding letters and digits and space
    ; space    white space (not quite the same as \s)
    ; upper    upper case letters
    ; word     "word" characters (same as \w)
    ; xdigit   hexadecimal digits
    ;
    ; refer to PCRESYNTAX(3) at http://www.pcre.org/pcre.txt for more info about the syntax

     Static iRegEx
     Protected iRetVal = -1 ; regex error
     
     If regex$
        If iRegEx > 0
            FreeRegularExpression(iRegEx)
        EndIf   
        iRegEx = CreateRegularExpression(#PB_Any, regex$)
     EndIf
     
     If iRegEx
        iRetVal = MatchRegularExpression(iRegEx, text$)   
     EndIf
     
     ProcedureReturn iRetVal
    EndProcedure



r$ = "^(?i)[A-Z0-9+_.-]+@[A-Z0-9.-]+$" ; not too strict email address validator
Debug RegExMatch("president@whitehouse.org", r$) ; 1
Debug RegExMatch("president") ; 0
Debug RegExMatch("@whitehouse.org") ; 0
Debug RegExMatch("pre$ident@whitehouse.org") ; 0
Debug RegExMatch("user@host")                ; 1
Debug RegExMatch("toto48.bob@oranget.fr")                ; 1
Debug RegExMatch("tito-jean01.bob@orange-nt.fr")                ; 1
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: trouver des adresses courriels

Message par falsam »

@Ar-s : Ton code ne permet pas d'extraire le ou les adresse emails. Hors c'est ce que cherche à faire YvesRossignol :wink:
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: trouver des adresses courriels

Message par falsam »

Marc56 a écrit :L'expression n'est pas complètement au point car elle permet plusieurs points consécutif.
de cette maniére on obtient la liste des email contenu dans un texte.

Code : Tout sélectionner

If OpenFile(0, "FichierSource.txt")
  While Not Eof(0)
    Full_Text$ + ReadString(0) + #CRLF$
  Wend 
  CloseFile(0)
Else
  End
EndIf

RegEx$ = "\S+@\S+|\{(?:\w+, *)+\w+\}@[\w.-]+"


If CreateRegularExpression(1, RegEx$, #PB_RegularExpression_NoCase)
  If ExamineRegularExpression(1, Full_Text$)
    While NextRegularExpressionMatch(1)
      Email$ = RegularExpressionMatchString(1)
      Debug Email$
    Wend
  Else
    End
  EndIf
EndIf
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Marc56
Messages : 2198
Inscription : sam. 08/févr./2014 15:19

Re: trouver des adresses courriels

Message par Marc56 »

Bon, je corrige les copies 8)

@Ar-S

Code : Tout sélectionner

^(?i)[A-Z0-9+_.-]+@[A-Z0-9.-]+$
  • Ton expression est bonne mais ne peut prendre que les lignes qui contiennent uniquement une adresse email.
    Si tu veux extraire des emails dans le texte, il faut supprimer les balises de début de ligne (^) et fin de ligne ($)
    Remplace les deux par \b (qui signifie boundary (borne) = espace, saut de ligne ou tab)
  • Ton expression autorise aussi les domaines à une seule lettre (ce qui à ma connaissance n'existe pas)
  • Bonne idée le (?i) qui est l'équivalent du #PB_RegularExpression_NoCase
@falsam

Code : Tout sélectionner

\S+@\S+|\{(?:\w+, *)+\w+\}@[\w.-]+
  • Ton expression prend aussi les accents, qui à ma connaissance, pour l'instant ne sont pas autorisés dans les adresses email.
  • Elle ignore les emails isolées sur une seule ligne.
  • Ton expression autorise aussi les domaines à une seule lettre (ce qui à ma connaissance n'existe pas)
:wink:
Dernière modification par Marc56 le jeu. 23/févr./2017 13:28, modifié 1 fois.
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: trouver des adresses courriels

Message par Ar-S »

Bon bah avec tout ça Yves devrait s'en sortir :mrgreen:
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: trouver des adresses courriels

Message par falsam »

@Marc : Je ne sais pas pourquoi j'ai publié mon code car le tien fonctionne bien. ! Ceci dit :
Ton expression autorise aussi les domaines à une seule lettre (ce qui à ma connaissance n'existe pas)
http://www.j.fr/ et aussi https://www.ovh.com/fr/news/a1719.domains-courts-en-fr

Petite précision tout comme le mot naze (Oui ça ne veut rien dire), les domaines avec accent existent (Merci à l'afnic.fr pour cette aberrante initiative. Heureusement, ça ne cyber-squatte pas trop pour le moment.
- Un exemple wikipédia.fr (Merci Gandi) redirigé vers wikipedia.fr

Et il existe aussi des adresses mail accentuées mais heureusement elles sont rares.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Marc56
Messages : 2198
Inscription : sam. 08/févr./2014 15:19

Re: trouver des adresses courriels

Message par Marc56 »

Merci pour cette mise à jour :P

Outch! 8O :arrow: https://fr.wikipedia.org/wiki/Adresse_% ... axe_exacte

:!: Pour ceux qui veulent s'y essayer: un mixte (Fr et Us de wikipedia) d'adresses qui doivent matcher et non matcher

Code : Tout sélectionner

Exemples d'adresses valides :

    Abc@example.com
    Abc@10.42.0.1
    Abc.123@example.com
    user+mailbox/department=shipping@example.com
    !#$%&'*+-/=?^_`.{|}~@example.com
    "Abc@def"@example.com
    "Fred Bloggs"@example.com
    "Joe.\\Blow"@example.com
    Loïc.Accentué@voilà.fr8
    prettyandsimple@example.com
    very.common@example.com
    disposable.style.email.with+symbol@example.com
    other.email-with-dash@example.com
    x@example.com (one-letter local-part)
    "much.more unusual"@example.com
    "very.unusual.@.unusual.com"@example.com
    "very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com
    example-indeed@strange-example.com
    admin@mailserver1 (local domain name with no TLD)
    #!$%&'*+-/=?^_`{}|~@example.org
    "()<>[]:,;@\\\"!#$%&'-/=?^_`{}| ~.a"@example.org
    " "@example.org (space between the quotes)
    example@localhost (sent from localhost)
    example@s.solutions (see the List of Internet top-level domains)
    user@localserver
    user@tt (although ICANN highly discourages dotless email addresses)
    user@[IPv6:2001:DB8::1] 

Exemples d'adresses non valides :

    Abc.example.com le caractère @ manque.
    Abc.@example.com Le caractère . est situé juste avant le caractère @ .
    Abc..123@example.com  Le caractère . apparaît deux fois de suite.
    Abc.example.com (no @ character)
    A@b@c@example.com (only one @ is allowed outside quotation marks)
    a"b(c)d,e:f;g<h>i[j\k]l@example.com (none of the special characters in this local-part are allowed outside quotation marks)
    just"not"right@example.com (quoted strings must be dot separated or the only element making up the local-part)
    this is"not\allowed@example.com (spaces, quotes, and backslashes may only exist when within quoted strings and preceded by a backslash)
    this\ still\"not\\allowed@example.com (even if escaped (preceded by a backslash), spaces, quotes, and backslashes must still be contained by quotes)
    1234567890123456789012345678901234567890123456789012345678901234+x@example.com (too long)
    john..doe@example.com (double dot before @) 
Heureusement que jusqu'ici la plupart des administrateurs de messagerie restreignent la créativité des utilisateurs quant au choix de leur email 8)
Jusqu'ici la plus exotique que j'ai croisé comportait un '+' (système utilisé par les alias gmail)

Si en plus on ajoute les jeux de caractères entre applications... :roll: :|

Voilà déjà une expression pour prendre les accents et quelques autres caractères.

Code : Tout sélectionner

[A-Z0-9àçéèêëîïôöùüÂÇÉÈÊËÎÏÔÖÙÜ.+-\\/]+@([A-Z0-9àçéèêëîïôöùüÂÇÉÈÊËÎÏÔÖÙÜ.+-\\/]+\.[A-Z0-9]+|[A-Z0-9àçéèêëîïôöùüÂÇÉÈÊËÎÏÔÖÙÜ.+-\\/]+)
(Très moche, car je n'ai pas regardé comment PB gère les références arrière (s'il les gère))
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: trouver des adresses courriels

Message par boby »

Code : Tout sélectionner

text$ = "ceci est markatrouver un exemple markatrouver de comment utiliser markatrouver la fonction markatrouver stringfield"
For loop = 1 To CountString(text$,"markatrouver")+1
  Debug StringField(text$,loop,"markatrouver")
Next loop
Marc56
Messages : 2198
Inscription : sam. 08/févr./2014 15:19

Re: trouver des adresses courriels

Message par Marc56 »

Voici une regex qui va matcher les adresses utilisées en standard

:arrow: Je ne traite pas les caractères accentués, car dans la réalité personne ne le utilise.
Raison principale: nécessité d'utiliser un clavier virtuel pour taper les caractères qui ne sont pas sur son propre clavier.

Code : Tout sélectionner

([\w\d.+-=/]+|"[\w\d \.+-=/\\@]+")@([\w\d.+-=]+.|[\w\d\:\[\]]+)
En PB on doit traiter à part les " donc ça donne ça:

Code : Tout sélectionner

RegEx$ = "([\w\d.+-=/!]+|" + Chr(34) + "[\w\d \.+-=/\\@]+" + Chr(34) + ")@([\w\d.+-=]+.|[\w\d\:\[\]]+)"
Adresses prises:
  • Adresses classiques (lettres, chiffres, _, .)
  • Adresses plus rares, contenant +-._/\!
  • Adresses "en dur" IPv4 et V6 (ex: user@[IPv6:2001:DB8::1])
  • Adresses contenant un espace ou un @ si encapsulées par des "" (ex: "much.more unusual"@example.com)
  • Adresses sans tld
Adresses prises mais en erreur:
(à exclure au niveau programme ou par une deuxième regex)
:idea: Comme pour les requêtes SQL il est plus rapide de filtrer à nouveau un résultat que de faire une énorme ligne.
  • Plusieurs points (ex: Abc..123@example.com)
  • Un point devant l'arobase (ex: Abc.@example.com)
  • Plusieurs @ non encapsulées (ex: A@b@c@example.com)
  • Adresse trop longue (320 caractères (64 @ 255)
:wink:
Répondre