Grupos con nombre y grupos sin captura en regex
Los paréntesis hacen dos trabajos: agrupan y capturan. Cómo los grupos sin captura (?:…) agrupan sin capturar, cómo los grupos con nombre (?<year>…) hacen legibles las capturas, cómo volver a ellos con \k<name> y cómo lo escribe Python.

· 5 min de lectura
/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/
atrapa
- 2026-10-13
- 1999-12-31
- 2000-01-01
- 2026-02-28
deja libre
- 26-10-13
- 2026/10/13
- 2026-1-3
- 13-10-2026
Los paréntesis de una regex hacen dos trabajos a la vez. Agrupan, para que un cuantificador o un | se aplique a todo lo que hay dentro. Y capturan, guardando el texto con el que coincidieron para que puedas usarlo después.
A menudo solo quieres uno de los dos. Este artículo cubre los dos tipos de grupo que separan esos trabajos: los grupos sin captura y los grupos con nombre. Todos los ejemplos son interactivos, así que edita los patrones y mira cómo cambian las líneas.
01Los grupos normales capturan
Un grupo normal guarda lo que encontró, numerado desde 1 según la posición de su paréntesis de apertura:
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"
Eso funciona hasta que cambia el patrón. Añade un grupo cerca del principio y todos los números que vienen detrás se desplazan, y m[2] pasa a ser otra cosa sin avisar.
02Grupos sin captura: (?:…)
Escribe (?: en lugar de ( cuando necesites agrupar pero no te importe el texto. Aquí el grupo solo existe para que + repita “palabra y luego un espacio”:
/^(?:\w+ )+\w+$/Debe coincidir2/2
- two words
- one two three
No debe2/2
- single
- double space
Coincide exactamente igual que (\w+ )+\w+. La diferencia está solo en lo que recibes: ninguna captura que numerar y nada que se desplace cuando editas el patrón. Además es un poco más barato, porque el motor no guarda el texto.
Un buen hábito: usa (?:…) para cada grupo que no vayas a leer después. Así, los grupos numerados o con nombre que queden serán los que significan algo.
03Grupos con nombre: (?…)
Ponle un nombre a un grupo y léelo por su nombre en lugar de por su número:
/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/Debe coincidir2/2
- 2026-10-13
- 1999-12-31
No debe3/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"
Los grupos con nombre siguen teniendo número, así que m[1] es el año en ambos casos. Los nombres solo hacen que el código sobreviva a los cambios en el patrón.
También funcionan en los reemplazos, con $<name>:
"2026-10-13".replace(
/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/,
"$<d>/$<m>/$<y>",
); // "13/10/2026"
04Hacer referencia a un grupo: \k
Una referencia inversa (backreference) coincide con el mismo texto con el que coincidió antes un grupo. Con grupos con nombre, se escribe \k<name> en lugar de \1:
/^(?<quote>["']).*\k<quote>$/Debe coincidir2/2
- "hello"
- 'hello'
No debe2/2
- "hello'
- 'hello"
Así el patrón dice lo que significa, algo que \1 nunca consigue, y sigue funcionando si añades grupos delante.
05Python lo escribe de otra manera
Python tuvo grupos con nombre antes que nadie, con una 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
Así que la misma idea es (?<name>…) y \k<name> en JavaScript, pero (?P<name>…), (?P=name) y \g<name> en Python. El grupo sin captura (?:…) es igual en todas partes.
06Grupos que no capturan cada repetición
Una sorpresa más: un grupo dentro de un cuantificador solo conserva su última repetición.
"abc".match(/(\w)+/)[1]; // "c", not ["a", "b", "c"]
Si necesitas cada repetición, usa el modificador g con matchAll (o re.findall) sobre el patrón interior.
07Pruébalo
Las comillas tienen que coincidir. Usa un grupo y una referencia que vuelva a él:
Atrapa el texto entre comillas que se correspondan: "…" o '…'.
Objetivos · 0/5 atrapados
- "hi"objetivo
- 'hi'objetivo
- "it's"objetivo
- 'say "no"'objetivo
- ""objetivo
Inocentes · 0 errores
- "hi'inocente
- 'hi"inocente
- hiinocente
- "hiinocente
- hi"inocente
Escribe una regex: el tablero se actualiza mientras escribes.
08Lista de comprobación
( … )agrupa y captura.(?: … )solo agrupa.- Usa
(?: … )para cada grupo que no vayas a leer. (?<name> … )captura con nombre. Léelo con.groups.namey reemplaza con$<name>.\k<name>vuelve a coincidir con el mismo texto.- En Python:
(?P<name> … ),(?P=name)y\g<name>. - Un grupo repetido solo conserva su última repetición.
09Sigue practicando
- Patrones con truco es un pack de práctica con grupos de sobra.
- La sección de grupos y la de referencias inversas de la guía van más allá.