Grupos de Captura
Aprenda grupos de captura em expressões regulares JavaScript: grupos numerados, grupos nomeados (?<name>), grupos não-capturadores (?:) e como usá-los com match, matchAll e replace ($1, $<name>).
Um grupo de captura é uma parte de uma expressão regular envolvida em parênteses (...). Ele faz duas coisas: agrupa um trecho do padrão para que quantificadores e alternância se apliquem ao bloco inteiro, e memoriza o texto que foi correspondido para que você possa recuperá-lo depois.
É isso que transforma uma expressão regular de um simples teste sim/não em uma ferramenta de extração de dados. Em vez de apenas saber que uma data correspondeu, você pode extrair o ano, mês e dia como partes separadas. Esta página aborda grupos numerados, grupos nomeados, grupos não-capturadores e como os grupos se comportam com match, matchAll e replace.
Entendendo os Grupos de Captura
Quando uma correspondência é encontrada, a correspondência completa é armazenada no índice 0 do array de resultado, e cada grupo de captura é armazenado nos índices seguintes (1, 2, 3, …) na ordem em que os parênteses de abertura dos grupos aparecem, da esquerda para a direita.
Sintaxe e Uso Básico
Aqui está um exemplo simples:
match[0] é sempre a string correspondida inteira. match[1] e match[2] contêm o texto capturado pelo primeiro e segundo par de parênteses. Os grupos são numerados pelo ( de abertura, então mesmo grupos aninhados têm uma ordem previsível (veja abaixo).
Uso Avançado e Técnicas
Grupos de Captura Aninhados
Os grupos podem ser aninhados, permitindo correspondências de padrões mais complexas. A numeração segue cada parêntese de abertura da esquerda para a direita:
O grupo externo (grupo 1) captura foobar, enquanto os grupos internos (2 e 3) capturam foo e bar separadamente. Se um grupo é opcional e não participa da correspondência, seu slot é undefined.
Grupos Não-Capturadores
Às vezes você quer agrupar partes de um padrão — para aplicar um quantificador ou alternância — sem gastar um slot numerado nisso. Grupos não-capturadores usam (?:...):
Aqui foo é agrupado, mas não capturado, então bar passa a ser o grupo 1 em vez do grupo 2. Grupos não-capturadores mantêm seu array de resultado limpo e são ligeiramente mais rápidos quando você não precisa do texto correspondido.
Um uso comum é repetir um trecho sem capturar cada repetição:
Exemplos Práticos
Analisando Datas
Grupos de captura podem analisar e reformatar datas de strings:
Este código extrai o ano, mês e dia, e então formata a data em um estilo diferente.
Extraindo Informações de URLs
Outro caso de uso comum é extrair partes de uma URL:
Esta expressão regular captura o protocolo, domínio, caminho e string de consulta separadamente.
Dicas para Usar Grupos de Captura com Eficácia
- Planeje seus grupos: Pense com antecedência em quais partes do padrão você precisa capturar.
- Use Grupos Não-Capturadores quando necessário: Use
(?:...)para agrupamento sem captura e simplifique seu array de correspondências. - Grupos de Captura Nomeados: No JavaScript moderno (ES2018+), você pode usar grupos de captura nomeados para melhor legibilidade.
- Comportamento da Flag Global: Ao usar a flag
gcomString.prototype.match(), ela retorna um array de todas as strings correspondidas em vez dos grupos de captura. UseString.prototype.matchAll()para extração detalhada de grupos com a flag global.
Grupos de Captura Nomeados
Grupos numerados são frágeis: adicione um grupo no meio e todos os índices seguintes se deslocam. Grupos de captura nomeados (ES2018+) evitam isso rotulando cada grupo com (?<name>...). As capturas aparecem em um objeto groups em vez de (ou além dos) índices numerados:
Prefira grupos de captura nomeados para qualquer padrão além do trivial — eles tornam tanto a expressão regular quanto o código que a lê autodocumentado.
Usando Grupos com match, matchAll e replace
A forma como você lê os grupos capturados depende do método que você chama.
Sem a flag g — match retorna grupos
Um String.prototype.match() não-global retorna um único array de correspondência com todos os grupos, exatamente como nos exemplos acima. Esta é a forma mais comum de extrair um único registro.
Com a flag g — use matchAll para obter grupos
Quando você adiciona a flag global g, match() retorna um array simples apenas com as strings de correspondência completa — os grupos são perdidos. Para obter grupos de cada correspondência, use String.prototype.matchAll(), que retorna um iterador de arrays de correspondência (cada um com seu próprio objeto groups):
Referenciando grupos em replace
Em uma string de substituição de String.prototype.replace() você pode referenciar capturas por número com $1, $2, … ou por nome com $<name>:
Para maior controle, passe uma função para replace. Seus argumentos são a correspondência completa, depois cada grupo capturado e (se você usou nomes) um objeto groups final:
Retrorreferências
Quando um grupo capturou um texto, você pode corresponder esse mesmo texto novamente mais adiante no mesmo padrão usando uma retrorreferência — \\1 para grupos numerados ou \\k<name> para nomeados. Isso é útil para encontrar palavras repetidas ou fazer correspondência de aspas emparelhadas:
Retrorreferências são um tópico próprio — veja Retrorreferências em padrões para todos os detalhes.
Tópicos Relacionados
- Alternância (OR)
|— grupos são essenciais para delimitar a alternância. - Quantificadores
+ * ? {n}— aplique repetição a um grupo inteiro. - Quantificadores gananciosos e preguiçosos — controle o quanto um grupo consome.
- Retrorreferências
\1e\k<name>— reutilize texto capturado dentro de um padrão. - Padrões e flags — as flags
g,ie outras que afetam a correspondência.
Conclusão
Os grupos de captura em expressões regulares JavaScript oferecem uma forma robusta de trabalhar com padrões de string complexos. Ao dominar seu uso, você pode realizar manipulações de texto sofisticadas, extrair dados significativos e lidar com substituições com facilidade. Seja analisando datas, processando URLs ou reformatando strings, os grupos de captura fornecem a flexibilidade e o poder necessários para tarefas avançadas de processamento de texto. Explore estes exemplos, pratique com seus próprios padrões e aprimore suas habilidades em JavaScript para enfrentar qualquer desafio de manipulação de strings.