Retourner à la page d'accueil de TJS

JavaScript et les Expressions Régulières

Les expressions régulières sont des objets qui existent dans la plupart des langages de programmation, mais qui sont mal connus, car relativement difficiles à lire pour le non-initié.

Ce tutorial a pour objet de vous montrer comment les expressions régulières fonctionnent et surtout à quoi elles servent.

Je vous assure que vous ne pourrez plus vous en passer, même dans votre éditeur de texte habituel !

L'objet RegExp est aussi détaillé dans la référence du langage.

Quelques exemples pour commencer

Avant de voir comment programmer les expressions régulières, je pense qu'il faut d'abord voir à quoi cela peut servir !

Les expressions régulières permettent de réaliser des traitements sur des chaînes de caractères, traitements qui pourraient être assez fastidieux à réaliser sans l'aide de ces fameuses expressions.

1er exemple : Trouver des mots dans un texte

Comment savoir si un mot est présent dans un texte.

<form name="ex1">
<textarea name="texte" style="width:100%; height:50px;">Ceci est le texte dans lequel on va rechercher un mot.
Comment ça marche ?
Continuez la lecture, je vous assure que ça vaut le coup :)
</textarea>
<p>Mot à recherche : <input type=text name="mot" value="lecture"> <input type="button" value="Rechercher" onClick="searchRegExp1(this.form)">
</form>

La fonction de recherche de mot est ici :

function searchRegExp1(f) {
  var lemot = f.mot.value
  var exp=new RegExp(lemot, "g");
  if ( exp.test(f.texte.value) ) {
    console.log("Le mot ["+lemot+"] a été trouvé :)"); 
  } else {
    console.log("E R R E U R  !\nLe mot ["+lemot+"] n'est pas présent !!!!"); 
  }
}

Pour chercher le texte présent dans la zone textarea :

Emulation de la console

2ème exemple : Est-ce un login valide ?

La principale utilité des expressions régulières en JavaScript est de vérifier la saisie dans un formulaire.
Cette fonction vérifie que le login saisi est bien formaté : de 3 à 8 caractères et sans caractères spéciaux (uniquement des chiffres et des lettres).

<form name="ex2">
Saisissez un login : <input type=text name=login value="login"> 
<input type=button value="Vérifier le login" onClick="verifLogin(this.form.login.value)"><br>
Saisissez un login : <input type=text name=login2 value="login trop long"> 
<input type=button value="Vérifier le login" onClick="verifLogin(this.form.login2.value)">
</form>

Et la fonction de vérification :

function verifLogin(login) {
  var exp=new RegExp("^[a-zA-Z0-9]{3,8}$","g");
  if ( exp.test(login) ) {
    console.log("Le login ["+login+"] est valide :)"); 
  } else {
    console.log("E R R E U R  !\nLe login ["+login+"] n'est pas valide !!!!"); 
  }
}

Essayez le formulaire :

Emulation de la console

Effectivement, la syntaxe n'est pas évidente. Nous allons voir maintenant comment écrire et utiliser les objets RegExp.

Déclarer un objet RegExp

Il existe 2 manières pour déclarer un objet RegExp. La plus lisible est d'utiliser le constructeur RegExp() :

var reg=new RegExp(pattern, option);

Ici, reg est devenu un objet de type RegExp.
pattern est le motif associé, ce qui permet de faire le traitement. Son format est défini dans le paragraphe suivant.
option est une chaîne de caractère qui peut prendre les valeurs :
- "", vide, aucune option,
- "g", recherche globale sur toute la chaîne,
- "i", ignore la distinction majuscule/minuscule,
- "gi", cumul de g et i.
Une autre notation, plus compacte, mais moins lisible est utilisée :

var exp=/pattern/option;

Les 2 notations sont exactement équivalentes.

La syntaxe du motif pattern

Les éléments du motif

C'est bien l'écriture du motif qui va faire toute la puissance de votre expression régulière. Voici les principales syntaxes possibles :

MotifSignification
^Début de ligne ou de chaîne
$Fin de ligne ou de chaîne
.N'importe quel caractère
x|yCaractère x ou y
[abc]Groupe de caractères : n'importe lequel de ceux entre crochets
[a-z]Groupe de caractères : n'importe lequel de a à z
[^0-9]Groupe de caractères : tous sauf ceux entre crochets
(x)Expression parenthésée (mémorisée)
*Caractère précédent de 0 à X fois
+Caractère précédent de 1 à X fois
?Caractère précédent de 0 à 1 fois
{n}Caractère précédent exactement n fois
{n,}Caractère précédent au moins n fois
{n,m}Caractère précédent entre n et m fois
\N'est pas un caractère, sert de caractère d'échappement
\\Caractère \
\dChiffres (équivalent à [0-9])
\DSauf chiffres (équivalent à [^0-9])
\bFrontière de mot (espace, alinéa, ...)
\sCaractère d'espacement (espace, tabulation, saut de page, ...) équivalent à [ \f\n\r\t\v]
\SUn seul caractère sauf un espacement
\wN'importe quel caractère alphanumérique, y compris undescore (_) équivalent à [A-Za-z0-9_]
\WTout sauf un caractère alphanumérique équivalent à [^A-Za-z0-9_]

Explication de motif

Si on reprend l'exemple du contôle de login, le pattern valait : ^[a-zA-Z0-9]{3,8}$
La signification est :
^ : pour montrer le début de la chaine,
[a-zA-Z0-9] : pour les caractères alphanumérique de a à z, de A à Z et de 0 à 9,
{3,8} : pour indiquer qu'il faut une longueur de 3 à 8 caractères alphanumériques,
$ : pour interdire tout caractère après.

Pour tester qu'une saisie est un mail valide, voici la chaîne pattern à utiliser :
^[a-zA-Z0-9\-_]+[a-zA-Z0-9\.\-_]*@[a-zA-Z0-9\-_]+\.[a-zA-Z\.\-_]{1,}[a-zA-Z\-_]+
La signification de cette chaîne est logique également :
^ : début du mail
[a-zA-Z0-9\-_]+ : Au moins un caractère alphanumérique en début de mail
[a-zA-Z0-9\.\-_]* : Tous les caractères alphanumériques plus ., - et _ au moins 1 fois
@ : une fois arobase
[a-zA-Z0-9\-_]+ : Tous les caractères alphanumériques plus ., - et _ au moins 1 fois
\. : 1 fois le caractère .
[a-zA-Z0-9\.\-_]{1,} : Tous les caractères alphanumériques plus ., - et _ au moins 2 fois
[a-zA-Z0-9\-_]+ : Au moins un caractère alphanumérique en fin de mail

Les différentes possibilités des RegExp

L'objet RegExp possède plusieurs méthodes qui ont différents effets.
Nous avons déjà vu la méthode test() qui valide une chaîne de caractères en fonction d'un motif.
La méthode exec() retourne la première sous-chaîne correspondant au motif.

Sur l'objet String, il existe également des méthodes qui attendent en paramètres une expression régulière :
La méthode search() permet de trouver des occurences répondant aux critères d'une RegExp.
La méthode replace() permet de trouver et de remplacer des occurences répondant aux critères d'une RegExp.
La méthode match() permet de trouver des occurences répondant aux critères d'une RegExp.

Exemples d'utilisation de split()

Supposons une liste de noms séparés par des virgules, des espaces ou des points-virgules, mais dont le format n'est pas uniforme.
Les expressions régulières vont nous permettre de créer un tableau avec tous les noms correctement isolés.
Pour l'extraction par split(), cette fonction est utilisée :

function ExtraireNomSplit(chaine) {
  var exp=new RegExp("[, ;]+","g");
  var tabNom=chaine.split(exp);
  if (tabNom==null) {
    console.log("Problème dans l'expression !");
  } else {
    console.table(tabNom);
  }
}
var s="Dupond, Martin , Duran, Dubois ; Legrand,Petit,   Rock-Feller";
ExtraireNomSplit(s);

La méthode split() crée un tableau qui contient tous les éléments trouvés entre le séparateur défini par l'expression régulière dont le motif est [, ;]+. Le tableau est ici affiché dans la console du navigateur avec console.table().

Emulation de la console

Exemples d'utilisation de match()

La méthode match() crée un tableau qui contient tous les éléments qui correspondent à l'expression régulière.

function ExtraireNomMatch(chaine) {
  var exp=new RegExp("[a-zA-Z\-]+","g");
  var tabNom=chaine.match(exp);
  if (tabNom==null) {
    console.log("Problème dans l'expression !");
  } else {
    console.table(tabNom);
  }
}
var s="Dupond, Martin , Duran, Dubois ; Legrand,Petit,   Rock-Feller";
ExtraireNomMatch(s);

La méthode match() crée un tableau qui contient tous les éléments trouvés par l'expression régulière avec le motif [a-zA-Z\-]+. Le tableau est ici affiché dans la console.

Emulation de la console

Le résultat de l'extraction est le même. L'emploi de l'une ou l'autre des méthodes dépend des données. Avec split(), le motif de l'expression recherche les séparateurs. Avec match(), le motif de l'expression recherche les termes hors séparateurs.

Extraire des mails dans un texte

Voyons encore un exemple d'utilisation de match() avec la recherche d'adresses mail dans un texte. Bonjour Monsieur Tartempion. Nous avons bien noté votre nouvelle adresse mail@tartempion.com qui remplace votre adresse tartempion@yahoo.com Vous pouvez toujours nous contacter sur contact@toto.com !

function ExtraireMail(chaine) {
  var exp=new RegExp("[a-zA-Z0-9\-_]+[a-zA-Z0-9\.\-_]*@[a-zA-Z0-9\-_]+\.[a-zA-Z\.\-_]{1,}[a-zA-Z\-_]+","g");
  var tabMail=chaine.match(exp);
  if (tabMail==null) {
    console.log("Problème dans l'expression !");
  } else {
    console.table(tabMail);
  }
}

var msg="Bonjour Monsieur Tartempion.\n";
msg+="Nous avons bien noté votre nouvelle adresse mail@tartempion.com qui remplace votre adresse tartempion@yahoo.com  \n";
msg+="Vous pouvez toujours nous contacter sur contact@toto.com !";
ExtraireMail(msg);

A l'exécution, le script affiche dans la console le tableau des mails extraits de la chaine msg :

Emulation de la console

Extraire les paramètres d'une url

Grâce aux expressions régulières, on peut également extraire simplement les paramètres passés dans une url pour les traiter en JavaScript.

Cette fonction crée un tableau associatif avec tous les paramètres de l'url et leur valeur.

Voici la fonction qui crée le tableau de paramètres :

function TJS_ExtractURL(url) {
  var regexp=new RegExp("[?&]");
  var tab=url.split(regexp);
  /* Affichage du 1er tableau de travail */
  console.log("Tableau de travail intermédiaire");
  console.table(tab);
  
  /* Création du tableau associatif */
  var tabParam = new Array();
  for (var i=1; i<tab.length; i++ ){
    var tab2=tab[i].split("=");
    console.log(tab2);
    tabParam[ tab2[0] ] = tab2[1];	  	  
  }
  
  console.log("Tableau associatif des paramètres de l'url");
  console.table(tabParam);
}

var url="http://monsite.com/search.html?idsession=14864ggfdda&query=mot-cle&type=4&sort=A";
document.write(url);
TJS_ExtractURL(url)

Observez dans la log la progression du traitement des paramètres de cette url :

Emulation de la console

Notez qu'on utilise 2 fois split(). Une première pour déterminer un premier tableau tab contenant à l'indice 0, l'url de la page et ensuite les éléments de paramètres au format cle=valeur.

Une boucle parcourant ces éléments relance un nouvel appel à split(), cette fois-ci avec juste "=" comme paramètre pour isoler cle et qui sont ajoutés dans le tableau de résultats tabParam.

Remplacer des caractères

Les expressions régulières permettent également de remplacer des caractères dans une chaîne.
Cette fonction enlève les accents d'une chaîne :

function TJS_EnleverAccent(chaine) {
  chaine=chaine.replace(/[éèêë]/g,"e");
  chaine=chaine.replace(/[àâä]/g,"a");
  chaine=chaine.replace(/[ïî]/g,"i");
  chaine=chaine.replace(/[ùûü]/g,"u");
  chaine=chaine.replace(/[öô]/g,"o");
  return chaine;
}
var chaine="Une chaîne à traiter très accentuée !";
document.write(chaine);
console.log(TJS_EnleverAccent(chaine));

Dans la console, on affiche le résultat du traitement de cette chaine :

Emulation de la console

La méthode replace() attend 2 paramètres :
- Le premier une RegExp qui sert à trouver les sous-chaînes à remplacer
- Le seconde, une String qui remplace les sous-chaînes trouvées

Rendre une adresse url cliquable

Voici un autre exemple de remplacement un peu plus subtil. Il s'agit ici de rendre une url cliquable dans du code HTML :

function TJS_UrlCliquable(url) { 
  var exp1=/((ht|f)tps?:\/\/\S*)/gi; 
  return url.replace(exp1,"<a target='_blank' href='$1'>$1</a>"); 
}

var texte="<p>Voir l'assistant de création RegExp http://www.toutjavascript.com/service/regexp.php sur http://www.toutjavascript.com !";
document.write(texte);
document.write(TJS_UrlCliquable(texte));

Après traitement, l'url devient cliquable :

Emulation de la console

Détaillons le motif ((ht|f)tps?:\/\/\S*) :
- La première parenthèse désigne la première expression parenthésée, c'est-à-dire mémorisée
- (ht|f)tp signifie http ou ftp
- s? signifie avec un s ou non
- :\/\/ signifie :// (il faut ajouter le caractère d'échappement car / est aussi le créateur de RegExp)
- \S* signifie tout caractère autre qu'un séparateur d'espacement
- La parenthère fermante finalise l'expression mémorisée, c'est-à-dire l'url complète

Dans la chaîne de remplacement, on note le $1 qui rappelle la première expression mémorisée

L'assistant de création de RegExp

Les expressions régulières offrent une immense palette de possibilités. Il suffit d'imaginer.
Une expression régulière n'est jamais terminée. Il est toujours possible de l'améliorer et de l'enrichir.
A vous de jouer ! Pensez à bien tester les différents cas de figure possible car il y a souvent des surprises dans des cas particuliers.
r0bl0che nous a créé un outil indispensable :

L'assistant de création de RegExp


Tutoriel écrit par webmaster mis à jour le

Chercher une fonction, un objet, ...

Le 24/11/2017 13:49:38 sur php7 en 16.44 ms