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.
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.
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
:
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 :
Effectivement, la syntaxe n'est pas évidente. Nous allons voir maintenant comment écrire et utiliser les objets 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.
C'est bien l'écriture du motif qui va faire toute la puissance de votre expression régulière. Voici les principales syntaxes possibles :
|
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
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.
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().
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.
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.
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
:
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 :
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 Les expressions régulières permettent également de remplacer des caractères dans une chaîne. Dans la console, on affiche le résultat du traitement de cette chaine :
La méthode replace() attend 2 paramètres : Voici un autre exemple de remplacement un peu plus subtil. Il s'agit ici de rendre une url cliquable dans du code HTML :
Après traitement, l'url devient cliquable : Détaillons le motif Dans la chaîne de remplacement, on note le $1 qui rappelle la première expression mémorisée Les expressions régulières offrent une immense palette de possibilités. Il suffit d'imaginer."="
comme paramètre pour isoler cle
et tabParam
.
Remplacer des caractères
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));
- 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
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));
((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
L'assistant de création de RegExp
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 :