07 - Les groupes nommes
Ce que tu vas apprendre
- La syntaxe
(?<name>...)pour nommer tes groupes de capture - La back-référencé
\k<name>pour réutiliser un groupe nomme - L'objet
.groupsen JavaScript pour acceder aux captures - Parser des chaînes structurees (URLs, logs, dates ISO) proprement
Prerequisites
Quand tu commences a avoir 4 ou 5 groupes de capture dans une regex, acceder au bon résultat avec match[3] devient un exercice de comptage de parentheses. Tu relis ta regex, tu comptes sur tes doigts... et tu te trompes quand meme. Les groupes nommes reglent ce problème une bonne fois pour toutes.
La syntaxe de base
Un groupe nomme, c'est un groupe de capture classique avec un nom colle dessus :
(?<nom>pattern)
Au lieu de (\d{4}), tu ecris (?<annee>\d{4}). Le match fonctionne de la meme manière, mais tu peux ensuite acceder au résultat par son nom.
javascriptconst regex = /(?<annee>\d{4})-(?<mois>\d{2})-(?<jour>\d{2})/;
const match = "2026-03-29".match(regex);
console.log(match.groups.annee); // "2026"
console.log(match.groups.mois); // "03"
console.log(match.groups.jour); // "29"
// Les indices numeriques marchent toujours
console.log(match[1]); // "2026"
console.log(match[2]); // "03"
L'objet match.groups contient toutes les captures nommees. Fini le comptage de parentheses.
Back-référencé nommee avec \k
Tu connais deja \1 pour référencer le premier groupe. Avec les groupes nommes, tu utilises \k<nom> :
javascript// Detecter un mot repete
const regex = /(?<mot>\w+)\s+\k<mot>/;
console.log(regex.test("le le chat")); // true
console.log(regex.test("le chat chat")); // true
console.log(regex.test("le chat noir")); // false
C'est exactement la meme chose que (\w+)\s+\1, mais en lisible. Quand tu relis la regex 6 mois plus tard, \k<mot> te dit immédiatement ce qui se passe. \1 te dit... rien du tout.
Parser une URL
Voila un cas concret ou les groupes nommes brillent. Parser les composants d'une URL :
javascriptconst urlRegex = /^(?<protocole>https?):\/\/(?<domaine>[^/:]+)(?::(?<port>\d+))?(?<chemin>\/[^?#]*)?(?:\?(?<query>[^#]*))?(?:#(?<fragment>.*))?$/;
const url = "https://api.example.com:8080/users/42?sort=name#top";
const match = url.match(urlRegex);
console.log(match.groups);
// {
// protocole: "https",
// domaine: "api.example.com",
// port: "8080",
// chemin: "/users/42",
// query: "sort=name",
// fragment: "top"
// }
Compare ca avec la version sans noms. Tu aurais match[1] a match[6] et aucune idee de quel indice correspond a quoi sans relire la regex entière. Avec .groups, le destructuring devient naturel :
javascriptconst { protocole, domaine, port, chemin } = match.groups;
Parser des lignes de log
Les logs serveur sont un terrain de jeu parfait pour les groupes nommes :
javascriptconst logRegex = /(?<date>\d{4}-\d{2}-\d{2}T[\d:.]+Z)\s+\[(?<niveau>INFO|WARN|ERROR|DEBUG)]\s+(?<service>\w+)\s+-\s+(?<message>.+)/;
const ligne = "2026-03-29T14:32:01.045Z [ERROR] auth-service - Token expired for user 1234";
const { groups } = ligne.match(logRegex);
console.log(groups.niveau); // "ERROR"
console.log(groups.service); // "auth-service"
console.log(groups.message); // "Token expired for user 1234"
Je fais ca régulièrement quand je dois analyser des fichiers de logs sur paltemps.fr. Plutot que d'utiliser un parser complet, une regex nommee suffit souvent pour extraire ce dont j'ai besoin.
Parser des dates ISO
Les dates ISO 8601 ont plusieurs variantes. Avec des groupes nommes, tu peux tout capturer proprement :
javascriptconst isoRegex = /^(?<annee>\d{4})-(?<mois>\d{2})-(?<jour>\d{2})(?:T(?<heure>\d{2}):(?<minute>\d{2})(?::(?<seconde>\d{2}))?(?:\.(?<ms>\d+))?(?<tz>Z|[+-]\d{2}:\d{2})?)?$/;
const date1 = "2026-03-29";
const date2 = "2026-03-29T14:30:00.123Z";
console.log(date1.match(isoRegex).groups);
// { annee: "2026", mois: "03", jour: "29", heure: undefined, ... }
console.log(date2.match(isoRegex).groups);
// { annee: "2026", mois: "03", jour: "29", heure: "14", minute: "30", seconde: "00", ms: "123", tz: "Z" }
Les groupes optionnels qui ne matchent pas deviennent undefined dans .groups. Pas d'erreur, pas de null, juste undefined.
Groupes nommes dans replace()
Tu peux utiliser {{body}}lt;nom> dans la chaîne de remplacement :
javascript// Reformater une date US en date FR
const dateUS = "03/29/2026";
const dateFR = dateUS.replace(
/(?<mois>\d{2})\/(?<jour>\d{2})\/(?<annee>\d{4})/,
"{{body}}lt;jour>/{{body}}lt;mois>/{{body}}lt;annee>"
);
console.log(dateFR); // "29/03/2026"
Et avec une fonction de remplacement, les groupes nommes arrivent en dernier argument :
javascriptconst result = "2026-03-29".replace(
/(?<annee>\d{4})-(?<mois>\d{2})-(?<jour>\d{2})/,
(match, ...args) => {
// Le dernier argument avant le dernier est l'objet groups
const groups = args.at(-1);
return `${groups.jour} mars ${groups.annee}`;
}
);
// "29 mars 2026"
Les pièges
Noms en double : tu ne peux pas utiliser le meme nom deux fois dans une regex (sauf dans des alternatives separees par | en ES2025+).
javascript// Erreur : nom en double
/(?<id>\d+)-(?<id>\w+)/ // SyntaxError
// OK en ES2025 : alternatives separees
/(?<id>\d+)|(?<id>\w+)/ // Valide
Support navigateur : les groupes nommes sont supportes depuis ES2018. Tous les navigateurs modernes les gerent. Node.js aussi depuis la version 10.
Pas de groupes nommes dans les classes de caractères : (?<nom>...) ne marche qu'a l'extérieur des [...].
Résumé
(?<nom>pattern)nomme un groupe de capture\k<nom>référencé un groupe nomme dans la regexmatch.groups.nomaccede au résultat en JavaScript{{body}}lt;nom>utilise un groupe nomme dansreplace()- Les groupes non-matches deviennent
undefineddans.groups - Utilise les groupes nommes des que tu as plus de 2 captures
Article précédent : 06 - Les back-références Article suivant : 08 - Lookahead et lookbehind