Groupes nommés et groupes non capturants en regex
Les parenthèses ont deux rôles : elles regroupent et elles capturent. Comment les groupes non capturants (?:…) regroupent sans capturer, comment les groupes nommés (?<year>…) rendent les captures lisibles, comment y faire référence avec \k<name>, et comment Python l'écrit.

· 5 min de lecture
/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/
à attraper
- 2026-10-13
- 1999-12-31
- 2000-01-01
- 2026-02-28
à épargner
- 26-10-13
- 2026/10/13
- 2026-1-3
- 13-10-2026
Dans une regex, les parenthèses font deux choses à la fois. Elles regroupent, pour qu'un quantificateur ou un | s'applique à tout leur contenu. Et elles capturent, en mémorisant le texte trouvé pour que vous puissiez l'utiliser plus tard.
Souvent, vous ne voulez que l'une des deux. Cet article présente les deux sortes de groupes qui séparent ces rôles : les groupes non capturants et les groupes nommés. Chaque exemple est interactif : modifiez les motifs et regardez les lignes changer.
01Les groupes simples capturent
Un groupe simple mémorise ce qu'il a trouvé, et il est numéroté à partir de 1 selon la position de sa parenthèse ouvrante :
const m = "2026-10-13".match(/(\d{4})-(\d{2})-(\d{2})/);
m[0]; // "2026-10-13", the whole match
m[1]; // "2026"
m[2]; // "10"
m[3]; // "13"
Ça marche, jusqu'au jour où le motif change. Ajoutez un groupe vers le début, et tous les numéros qui suivent se décalent : m[2] devient discrètement autre chose.
02Les groupes non capturants : (?:…)
Écrivez (?: au lieu de ( quand vous avez besoin de regrouper sans vous soucier du texte. Ici, le groupe n'existe que pour que + répète « un mot, puis un espace » :
/^(?:\w+ )+\w+$/Doit correspondre2/2
- two words
- one two three
Ne doit pas2/2
- single
- double space
Il trouve exactement la même chose que (\w+ )+\w+. La seule différence, c'est ce que vous récupérez : aucune capture à numéroter, et rien qui se décale quand vous modifiez le motif. C'est aussi un peu moins coûteux, puisque le moteur ne mémorise pas le texte.
Une bonne habitude : utilisez (?:…) pour chaque groupe dont vous ne réutilisez pas la capture. Ainsi, les groupes numérotés ou nommés qui restent sont ceux qui ont un sens.
03Les groupes nommés : (?…)
Donnez un nom à un groupe et lisez-le par son nom plutôt que par son numéro :
/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/Doit correspondre2/2
- 2026-10-13
- 1999-12-31
Ne doit pas3/3
- 26-10-13
- 2026/10/13
- 2026-1-3
const { year, month, day } =
"2026-10-13".match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/).groups;
year; // "2026"
Les groupes nommés reçoivent quand même un numéro, donc m[1] est l'année dans les deux cas. Les noms garantissent simplement que le code survit aux modifications du motif.
Ils fonctionnent aussi dans les remplacements, avec $<name> :
"2026-10-13".replace(
/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/,
"$<d>/$<m>/$<y>",
); // "13/10/2026"
04Y faire référence : \k
Une référence arrière correspond au même texte que celui trouvé plus tôt par un groupe. Avec les groupes nommés, on écrit \k<name> au lieu de \1 :
/^(?<quote>["']).*\k<quote>$/Doit correspondre2/2
- "hello"
- 'hello'
Ne doit pas2/2
- "hello'
- 'hello"
Le motif dit clairement ce qu'il veut dire, ce que \1 ne fait jamais, et il fonctionne toujours si vous ajoutez des groupes devant.
05Python l'écrit autrement
Python a été le premier à proposer les groupes nommés, avec un P :
import re
m = re.match(r"(?P<year>\d{4})-(?P<month>\d{2})", "2026-10")
m.group("year") # "2026"
m.groupdict() # {"year": "2026", "month": "10"}
re.sub(r"(?P<y>\d{4})-(?P<m>\d{2})", r"\g<m>/\g<y>", "2026-10") # "10/2026"
re.match(r"(?P<q>[\"']).*(?P=q)$", '"hi"') # backreference by name
La même idée s'écrit donc (?<name>…) et \k<name> en JavaScript, mais (?P<name>…), (?P=name) et \g<name> en Python. Le groupe non capturant (?:…) est le même partout.
06Les groupes répétés ne gardent que la dernière capture
Une dernière surprise : un groupe placé sous un quantificateur ne garde que sa dernière répétition.
"abc".match(/(\w)+/)[1]; // "c", not ["a", "b", "c"]
Si vous avez besoin de chaque répétition, utilisez plutôt le marqueur g avec matchAll (ou re.findall) sur le motif intérieur.
07À vous de jouer
Les guillemets doivent aller ensemble. Utilisez un groupe et une référence arrière vers lui :
Attrapez le texte encadré par des guillemets assortis : "…" ou '…'.
Cibles · 0/5 attrapées
- "hi"cible
- 'hi'cible
- "it's"cible
- 'say "no"'cible
- ""cible
Innocents · erreurs : 0
- "hi'innocent
- 'hi"innocent
- hiinnocent
- "hiinnocent
- hi"innocent
Tapez une regex — le plateau se met à jour en direct.
08Récapitulatif
( … )regroupe et capture.(?: … )ne fait que regrouper.- Utilisez
(?: … )pour chaque groupe dont vous ne réutilisez pas la capture. (?<name> … )capture par nom. Lisez-le avec.groups.name, remplacez avec$<name>.\k<name>retrouve le même texte.- Python :
(?P<name> … ),(?P=name)et\g<name>. - Un groupe répété ne garde que sa dernière répétition.
09Continuez à vous entraîner
- Motifs retors est un pack d'entraînement plein de groupes.
- Les sections du guide sur les groupes et les références arrière vont plus loin.