trouver des adresses courriels
-
- Messages : 133
- Inscription : lun. 28/mars/2016 19:09
trouver des adresses courriels
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
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
- Kwai chang caine
- Messages : 6989
- Inscription : sam. 23/sept./2006 18:32
- Localisation : Isere
Re: trouver des adresses courriels
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
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
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

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
Re: trouver des adresses courriels
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
Ou alors une ligne d'expression régulière
L'expression n'est pas complètement au point car elle permet plusieurs points consécutif.

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

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

Re: trouver des adresses courriels
Yop,
Extrait d'un code de Luis qui fonctionne très bien.
J'ai ajouté qques tests et ça marche bien.
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
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳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
- falsam
- Messages : 7324
- Inscription : dim. 22/août/2010 15:24
- Localisation : IDF (Yvelines)
- Contact :
Re: trouver des adresses courriels
@Ar-s : Ton code ne permet pas d'extraire le ou les adresse emails. Hors c'est ce que cherche à faire YvesRossignol 

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%
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
- falsam
- Messages : 7324
- Inscription : dim. 22/août/2010 15:24
- Localisation : IDF (Yvelines)
- Contact :
Re: trouver des adresses courriels
de cette maniére on obtient la liste des email contenu dans un texte.Marc56 a écrit :L'expression n'est pas complètement au point car elle permet plusieurs points consécutif.
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%
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Re: trouver des adresses courriels
Bon, je corrige les copies
@Ar-S


@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
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)

Dernière modification par Marc56 le jeu. 23/févr./2017 13:28, modifié 1 fois.
Re: trouver des adresses courriels
Bon bah avec tout ça Yves devrait s'en sortir 

~~~~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
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳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
- falsam
- Messages : 7324
- Inscription : dim. 22/août/2010 15:24
- Localisation : IDF (Yvelines)
- Contact :
Re: trouver des adresses courriels
@Marc : Je ne sais pas pourquoi j'ai publié mon code car le tien fonctionne bien. ! Ceci dit :
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.
http://www.j.fr/ et aussi https://www.ovh.com/fr/news/a1719.domains-courts-en-frTon expression autorise aussi les domaines à une seule lettre (ce qui à ma connaissance n'existe pas)
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%
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Re: trouver des adresses courriels
Merci pour cette mise à jour
Outch!
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
Heureusement que jusqu'ici la plupart des administrateurs de messagerie restreignent la créativité des utilisateurs quant au choix de leur email 
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...

Voilà déjà une expression pour prendre les accents et quelques autres caractères.(Très moche, car je n'ai pas regardé comment PB gère les références arrière (s'il les gère))

Outch!



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 @)

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...


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àçéèêëîïôöùüÂÇÉÈÊËÎÏÔÖÙÜ.+-\\/]+)
Re: trouver des adresses courriels
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
Re: trouver des adresses courriels
Voici une regex qui va matcher les adresses utilisées en standard
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.
En PB on doit traiter à part les " donc ça donne ça:
Adresses prises:
(à exclure au niveau programme ou par une deuxième regex)
Comme pour les requêtes SQL il est plus rapide de filtrer à nouveau un résultat que de faire une énorme ligne.


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\:\[\]]+)
Code : Tout sélectionner
RegEx$ = "([\w\d.+-=/!]+|" + Chr(34) + "[\w\d \.+-=/\\@]+" + Chr(34) + ")@([\w\d.+-=]+.|[\w\d\:\[\]]+)"
- Adresses classiques (lettres, chiffres, _, .)
- Adresses plus rares, contenant +-._/\!
- Adresses "en dur" IPv4 et V6 (ex: user@[IPv6
DB8::1])
- Adresses contenant un espace ou un @ si encapsulées par des "" (ex: "much.more unusual"@example.com)
- Adresses sans tld
(à exclure au niveau programme ou par une deuxième regex)

- 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)
