![]() |
Christian Kruse: |
|
|
|
| Adresse électronique: | |
| Homepage-URL: |
Il s'agit ici d'un article traduit de l'allemand par la rédaction de SELFHTML actuel. Veuillez poser vos questions relatives à cet article uniquement à son auteur, prenant compte que celui-ci ne maîtrise peut-être pas la langue française!
Vérifier complètement la syntaxe correcte d'une adresse électronique conformément à
RFC819
n'est malheureusement pas possible avec une seule RegEx.
Cela est dû au fait que quelques éléments d'une adresse électronique peuvent malheureusement apparaître imbriqués. Avec des expressions régulières, on ne peut cependant explorer qu'à un certain niveau. Ce qui est toutefois possible, c'est une exclusion relativement fiable d'adresses électroniques à la syntaxe erronée. Mais il est nécessaire que vous sachiez qu'une adresse électronique dont la syntaxe est correcte n'est pas forcément une adresse électronique valide! Pour constater si l'adresse est valide, vous ne pouvez qu'envoyer un courriel à l'utilisateur en vous faisant accuser réception (par exemple en visitant un lien envoyé dans le courriel). Cette vérification supplémentaire est malgré tout judicieuse: par la validation des saisies de l'utilisateur, les failles dans la sécurité sont bouchées (Mot-clé: Problème open() lors de l'envoi de courriels avec Sendmail) et le trafic dinminue, car naturellement, il est inutile d'envoyer de courriel à des adresses électroniques invalides.
Dans les exemples, c'est la syntaxe Perl qui est employée. Mais la RegEx est tout aussi valable en JavaScript, PHP ou bien C.
Tout d'abord, quelques remarques sur la construction des adresses électroniques: celles-ci sont toujours construites sur le modèle user@host. Ici, la partie user (=utilisateur) ne doit contenir que les signes a-zA-Z0-9_.- et doit commencer par a-zA-Z0-9.
Un utilisateur peut mentionner en alternative une chaîne de caractères entre guillemets. "Christian Kruse"@wwwtech.de est par exemple une adresse électronique valide. Dans cette chaîne de caractères, peut se trouver un caractère ASCII au choix, mais les signes " doivent être masqués par une barre oblique inversée \:
"Christian \"CK\" Kruse"@wwwtech.de. Ce qui nous amène à l'expression régulière partielle suivante:
my $nonascii = "\x80-\xff"; # Tous les signes supérieurs à Char 128 ne sont plus des caractères ASCII. my $nqtext = "[^\\\\$nonascii\015\012\"]"; # Tous les signes qui *ne doivent pas* être placés entre guillemets my $qchar = "\\\\[^$nonascii]"; # vérifie les signes entre guillemets my $normuser = '[a-zA-Z0-9][a-zA-Z0-9_.-]*'; # voir les remarques plus haut my $quotedstring = "\"(?:$nqtext|$qchar)+\""; # une chaîne de caractères entre guillemets comporte des caractères non masqués et des caractères masqués my $user_part = "(?:$normuser|$quotedstring)"; # la partie utilisateur comporte la chaîne de caractères utlisateur normale ou une chaîne de caractères entre guillemets |
Le nom de l'hébergeur est un peu plus difficile à vérifier: En général un nom d'hébergeur comporte n sous-domaines, un nom de domaine et un domaine de premier niveau (Toplevel-Domain), par exemple "fr". Ici un sous-domaine peut comporter les caractères a-zA-Z0-9._- et doit contenir au moins deux de ces signes. Il doit cependant commencer uniquement par un des caractères a-zA-Z0-9 et se terminer par un point.
Ce qui nous amène à l'expression régulière partielle suivante:
my $dom_mainpart = '[a-zA-Z0-9][a-zA-Z0-9._-]*\\.'; # La partie domaine
my $dom_subpart = '(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*'; # la partie sous-domaine, 0-n sous-domaines
my $dom_tldpart = '[a-zA-Z]{2,5}'; # le domaine de premier niveau
my $domain_part = "$dom_subpart$dom_mainpart$dom_tldpart";
|
Il ne reste maintenant qu'à prendre en compte un éventuel 'mailto:'. Cela se fait très simplement avec une petite expression partielle:
my $protocol = '(?:mailto:)'; # le 'mailto:' est facultatif |
Et voici l'expression régulière complète prête à copier:
#!/usr/bin/perl -w
use strict;
### RegEx begin
my $nonascii = "\x80-\xff"; # Les caractères Non-ASCII ne sont pas permis
my $nqtext = "[^\\\\$nonascii\015\012\"]";
my $qchar = "\\\\[^$nonascii]";
my $protocol = '(?:mailto:)';
my $normuser = '[a-zA-Z0-9][a-zA-Z0-9_.-]*';
my $quotedstring = "\"(?:$nqtext|$qchar)+\"";
my $user_part = "(?:$normuser|$quotedstring)";
my $dom_mainpart = '[a-zA-Z0-9][a-zA-Z0-9._-]*\\.';
my $dom_subpart = '(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*';
my $dom_tldpart = '[a-zA-Z]{2,5}';
my $domain_part = "$dom_subpart$dom_mainpart$dom_tldpart";
# L'expression régulière proprement-dite
my $regex = "$protocol?$user_part\@$domain_part";
### RegEx end
# Petit bout d'essai:
my @emails = (
'ckruse@wwwtech.de',
'"Christian Kruse"@wwwtech.de',
'"Christian \"CK\" Kruse"@wwwtech.de',
'"Christian"ckruse@wwwtech.de'
);
foreach my $email (@emails) {
if($email =~ /^$regex$/) {
print "Adresse électronique valide\n";
}
else {
print "Adresse électronique non valide\n";
}
}
# fin du fichier (eof)
|
Confomément à ce qui précède, j'ai encore implémenté les fonctions suivantes dans les différents langages:
Un petit module qui doit être placé dans le même répertoire que le script nommé CheckEMail.pm. Il peut alors être incorporé comme suit:
use CheckEMail qw/isEmail/;
if(isEmail($email)) {
print "Adresse électronique valide!\n";
}
|
Ici donc le texte source du module:
package CheckEMail;
use strict;
use vars qw($VERSION @ISA @EXPORT_OK $MailRegEx);
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(isEmail $MailRegEx);
$VERSION = '1.0';
### RegEx begin
my $nonascii = "\x80-\xff"; # Les caractères Non-ASCII ne sont pas permis
my $nqtext = "[^\\\\$nonascii\015\012\"]";
my $qchar = "\\\\[^$nonascii]";
my $protocol = '(?:mailto:)';
my $normuser = '[a-zA-Z0-9][a-zA-Z0-9_.-]*';
my $quotedstring = "\"(?:$nqtext|$qchar)+\"";
my $user_part = "(?:$normuser|$quotedstring)";
my $dom_mainpart = '[a-zA-Z0-9][a-zA-Z0-9._-]*\\.';
my $dom_subpart = '(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*';
my $dom_tldpart = '[a-zA-Z]{2,5}';
my $domain_part = "$dom_subpart$dom_mainpart$dom_tldpart";
$MailRegEx = "$protocol?$user_part\@$domain_part";
### RegEx end
sub isEmail($) {
my $mail = shift;
return $mail =~ /^$MailRegEx$/o;
}
1;
# eof
|
Pour PHP, c'est simplement une petite fonction qui renvoie true oder false:
function check_email($email) {
// RegEx begin
$nonascii = "\x80-\xff"; # Les caractères Non-ASCII ne sont pas permis
$nqtext = "[^\\\\$nonascii\015\012\"]";
$qchar = "\\\\[^$nonascii]";
$protocol = '(?:mailto:)';
$normuser = '[a-zA-Z0-9][a-zA-Z0-9_.-]*';
$quotedstring = "\"(?:$nqtext|$qchar)+\"";
$user_part = "(?:$normuser|$quotedstring)";
$dom_mainpart = '[a-zA-Z0-9][a-zA-Z0-9._-]*\\.';
$dom_subpart = '(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*';
$dom_tldpart = '[a-zA-Z]{2,5}';
$domain_part = "$dom_subpart$dom_mainpart$dom_tldpart";
$regex = "$protocol?$user_part\@$domain_part";
// RegEx end
return preg_match("/^$regex$/",$email);
}
|
À copier simplement dans la source et à utiliser comme suit:
if(check_email($email)) {
echo "L'adresse électronique n'est pas valide!"
}
|
Même pour JavaScript existe une version qui ne fonctionne cependant qu'avec NN4, Mozilla, IE à partir de la version 5 et Opera à partir de la version 6. Je remercie ici
Antje Hofmann, qui a mis au point l'expression régulière sous JavaScript. La fonction suivante avec l'expression régulière légèrement transformée est simplement à placer dans le document HTML entre <script></script> et à appeler en cas de besoin.
function checkEmail(email) {
var proto = "(mailto:)?";
var usr = "([a-zA-Z0-9][a-zA-Z0-9_.-]*|\"([^\\\\\x80-\xff\015\012\"]|\\\\[^\x80-\xff])+\")";
var domain = "([a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*[a-zA-Z0-9][a-zA-Z0-9._-]*\\.[a-zA-Z]{2,5}";
var regex = "^" + proto + "?" + usr + "\@" + domain + "$";
var rgx = new RegExp(regex);
return rgx.exec(email) ? true : false;
}
|
Quand elle est appelée, la fonction retourne true ou false.
Les adresses suivantes sont recommandées pour une meilleure compréhension de l'exemple ci-dessus, ou pour apprendre d'autres possibilités et détails.
Vérifier la syntaxe d'adesses électroniques
SELFHTML: Expressions régulières
SELFHTML: RegExp
Les regexp sur www.expreg.com
perldoc perlre
RFC819