// Web

Les expressions régulières en JavaScript (regex)

Une expression régulière (ou regex) est un motif qui décrit un ensemble de chaînes de caractères. En JavaScript, c’est l’outil idéal pour valider une saisie, extraire une donnée ou remplacer du texte selon une règle. La syntaxe intimide au premier abord, mais elle repose sur un petit nombre de briques. Ce guide les passe toutes en revue, avec des exemples réels prêts à l’emploi.

Deux façons de créer une regex

JavaScript propose deux syntaxes équivalentes pour définir une expression régulière.

La notation littérale

Encadrée par des slashs, elle est la plus courante et la plus lisible pour un motif fixe.

const motif = /bonjour/;

Le constructeur RegExp

Utile quand le motif est construit dynamiquement à partir d’une variable. Attention : dans une chaîne, l’antislash doit être doublé.

const mot = "bonjour";
const motif = new RegExp(mot);        // équivalent à /bonjour/
const chiffres = new RegExp("\\d+");   // équivalent à /\d+/

Retenez la règle : littéral pour un motif connu à l’écriture, RegExp pour un motif calculé à l’exécution.

Les méthodes de test et de recherche

Une fois la regex définie, plusieurs méthodes l’exploitent, portées soit par l’objet regex, soit par les chaînes.

test() : vrai ou faux

test() renvoie un booléen indiquant si le motif est présent. C’est la méthode de choix pour valider une saisie.

const aUnChiffre = /\d/;
aUnChiffre.test("abc123"); // true
aUnChiffre.test("abcdef"); // false

match() : extraire les correspondances

String.prototype.match() renvoie la première correspondance (ou null). Avec le flag g, il renvoie un tableau de toutes les correspondances.

"Il y a 3 chats et 12 chiens".match(/\d+/);
// ["3", index: 7, ...] — seulement la première

"Il y a 3 chats et 12 chiens".match(/\d+/g);
// ["3", "12"] — toutes les occurrences

matchAll() : correspondances avec détails

matchAll() renvoie un itérateur donnant chaque correspondance avec ses groupes et sa position. Indispensable quand on a besoin des groupes de capture sur plusieurs occurrences.

const texte = "prix: 10€, port: 5€";
for (const m of texte.matchAll(/(\d+)€/g)) {
  console.log(`Montant ${m[1]} à l'index ${m.index}`);
}
// Montant 10 à l'index 6
// Montant 5 à l'index 17

replace() et replaceAll() : substituer

replace() remplace les correspondances. Avec le flag g (ou replaceAll), toutes sont traitées. On peut réutiliser les groupes capturés via $1, $2

"2026-01-08".replace(/(\d{4})-(\d{2})-(\d{2})/, "$3/$2/$1");
// "08/01/2026"

"un  deux   trois".replace(/\s+/g, " ");
// "un deux trois" — normalise les espaces

replace accepte aussi une fonction de remplacement, qui reçoit la correspondance et ses groupes :

"prix: 10, 20, 30".replace(/\d+/g, (n) => n * 2);
// "prix: 20, 40, 60"

Les classes de caractères

Une classe définit un ensemble de caractères acceptés à une position. Entre crochets, on énumère ou on donne une plage.

/[aeiou]/       // une voyelle
/[a-z]/         // une lettre minuscule
/[A-Za-z0-9]/   // un caractère alphanumérique
/[^0-9]/        // tout SAUF un chiffre (le ^ nie la classe)

JavaScript fournit des raccourcis pour les classes fréquentes :

/\d/   // un chiffre        → équivaut à [0-9]
/\D/   // tout sauf chiffre → équivaut à [^0-9]
/\w/   // caractère de mot  → [A-Za-z0-9_]
/\W/   // tout sauf ça
/\s/   // espace blanc (espace, tab, saut de ligne)
/\S/   // tout sauf espace
/./    // n'importe quel caractère (sauf saut de ligne)

Dans une classe entre crochets, la plupart des métacaractères perdent leur sens spécial. Pour un point littéral hors classe, échappez-le : /\./.

Les quantificateurs

Un quantificateur indique combien de fois l’élément précédent doit apparaître.

/a*/     // 0 ou plus
/a+/     // 1 ou plus
/a?/     // 0 ou 1 (optionnel)
/a{3}/   // exactement 3
/a{2,4}/ // entre 2 et 4
/a{2,}/  // 2 ou plus

Exemple concret : un code postal français (5 chiffres) :

/^\d{5}$/.test("75001"); // true
/^\d{5}$/.test("7501");  // false

Gourmandise et paresse

Par défaut, les quantificateurs sont gourmands : ils capturent le plus possible. Ajouter ? les rend paresseux (le minimum).

"<b>gras</b>".match(/<.+>/)[0];   // "<b>gras</b>" — gourmand
"<b>gras</b>".match(/<.+?>/)[0];  // "<b>"         — paresseux

Ce détail explique bien des surprises lors de l’extraction de balises ou de portions de texte.

Les ancres et les limites

Les ancres ne consomment aucun caractère : elles fixent une position.

/^Bonjour/   // début de chaîne
/monde$/     // fin de chaîne
/^exact$/    // la chaîne entière doit correspondre
/\bchat\b/   // "chat" comme mot entier (limite de mot)

La limite de mot \b évite les fausses correspondances : /\bchat\b/ reconnaît « le chat » mais pas « chatard ».

Les groupes de capture

Les parenthèses créent un groupe : elles regroupent une portion du motif et en mémorisent la valeur.

const m = "2026-01-08".match(/(\d{4})-(\d{2})-(\d{2})/);
m[0]; // "2026-01-08" — correspondance complète
m[1]; // "2026"
m[2]; // "01"
m[3]; // "08"

Groupes nommés

Plutôt que des index, on nomme les groupes avec (?<nom>...), ce qui rend le code bien plus lisible.

const { groups } = "2026-01-08".match(
  /(?<annee>\d{4})-(?<mois>\d{2})-(?<jour>\d{2})/
);
groups.annee; // "2026"
groups.jour;  // "08"

Groupes non capturants et alternatives

(?:...) groupe sans mémoriser (utile pour appliquer un quantificateur). Le pipe | exprime une alternative.

/(?:https?):\/\//         // groupe le protocole sans le capturer
/chat|chien|oiseau/       // l'un des trois mots
/^(oui|non)$/             // exactement "oui" ou "non"

Les flags (drapeaux)

Placés après le slash fermant, les flags modifient le comportement de la regex.

/motif/g   // global : toutes les occurrences, pas seulement la première
/motif/i   // insensible à la casse (Chat = chat = CHAT)
/motif/m   // multiligne : ^ et $ collent à chaque ligne
/motif/s   // dotAll : le . matche aussi les sauts de ligne
/motif/u   // unicode : gère correctement les caractères hors BMP (émojis…)

On les combine librement :

"Chat CHAT chat".match(/chat/gi);
// ["Chat", "CHAT", "chat"]

Le flag i est particulièrement précieux pour valider des saisies utilisateur, insensibles à la casse par nature. La construction de ces motifs se manipule souvent avec les méthodes de tableau pour traiter les résultats.

Exemples concrets prêts à l’emploi

Voici des motifs courants, avec leurs limites. Une regex de validation reste toujours un compromis entre rigueur et simplicité.

Adresse email

const email = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
email.test("[email protected]"); // true
email.test("pas-un-email");           // false

Ce motif simple couvre l’immense majorité des cas réels. Une validation exhaustive de la norme est démesurément complexe : pour un email, mieux vaut un motif souple complété par un vrai envoi de confirmation.

Numéro de téléphone français

const tel = /^(?:\+33|0)\s?[1-9](?:[\s.-]?\d{2}){4}$/;
tel.test("06 12 34 56 78");  // true
tel.test("+33 6 12 34 56 78"); // true
tel.test("0612345678");      // true

URL

const url = /^https?:\/\/[^\s/$.?#].[^\s]*$/i;
url.test("https://coder-studio.fr/regex"); // true

Mot de passe robuste

Ici, on utilise des assertions avant (lookahead) pour imposer plusieurs conditions simultanées : au moins 8 caractères, une majuscule, une minuscule et un chiffre.

const mdp = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;
mdp.test("Azerty12"); // true
mdp.test("azerty");   // false

Extraire les hashtags d’un texte

const texte = "J'adore #javascript et les #regex #dev";
[...texte.matchAll(/#(\w+)/g)].map((m) => m[1]);
// ["javascript", "regex", "dev"]

Pièges à connaître

Quelques erreurs reviennent souvent avec les regex en JavaScript.

  • Le flag g et test() : une regex avec g conserve un état interne (lastIndex). Appeler test() plusieurs fois sur la même instance donne des résultats alternés. Pour une simple validation, n’utilisez pas g.
  • Oublier d’échapper : ., +, *, ?, (, ), [, \ ont un sens spécial. Pour les chercher littéralement, précédez-les d’un antislash : /\$/ pour un dollar.
  • Motif trop permissif : .* capture beaucoup, souvent trop. Préférez des classes précises et des quantificateurs paresseux quand c’est pertinent.

À retenir

Une regex se crée en littéral (/.../) ou via RegExp pour un motif dynamique. test() valide, match/matchAll extraient, replace substitue. Les classes de caractères (\d, \w, [a-z]) décrivent le contenu, les quantificateurs (+, *, {2,4}) la répétition, les ancres (^, $, \b) la position, et les groupes (...) capturent des portions. Les flags g et i sont vos alliés du quotidien. Commencez par des motifs simples et testez-les sur des cas limites avant de les complexifier.

À lire ensuite