SELFHTML

Christian Kruse:
Vérification de la syntaxe de l'adresse électronique par des expressions régulières

Page d'information: vue d'ensemble

vers le bas Christian Kruse
vers le bas Remarques sur le sujet
vers le bas Exemple et explications
vers le bas Liens contextuels

vers le bas 

Christian Kruse

Adresse électronique: adresse électronique CK1@wwwtech.de
Homepage-URL: page en langue allemande http://wwwtech.de/

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!

nach obenvers le bas 

Remarques sur le sujet

Vérifier complètement la syntaxe correcte d'une adresse électronique conformément à page en langue anglaise 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.

vers le hautvers le bas 

Exemple et explications

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:

Perl

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

PHP

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!"
}

JavaScript

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

vers le hautvers le bas 

Liens contextuels

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.

Page d'information Vérifier la syntaxe d'adesses électroniques
Page d'information: connexion exigée SELFHTML: Expressions régulières
Page d'information: connexion exigée SELFHTML: RegExp

Page en langue française Les regexp sur www.expreg.com

Page en langue anglaise perldoc perlre
Page en langue anglaise RFC819

vers le haut

© 2005 Page d'information: connexion exigée Informations