Regex em JavaScript
Aprenda expressões regulares (regex) em JavaScript: padrões, flags, métodos de string e RegExp, e os blocos essenciais para busca e validação de texto.
Introdução às Expressões Regulares (Regex) em JavaScript
As expressões regulares, conhecidas como regex, são sequências de caracteres que formam padrões de busca. São ferramentas essenciais na programação para tarefas de processamento de texto, como pesquisa, edição e manipulação de dados de string. O regex é utilizado em diversas áreas, como validação de dados, análise sintática, destaque de sintaxe e muito mais.
Por exemplo, você pode verificar rapidamente se uma string se parece com um endereço de e-mail:
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRegex.test("[email protected]")); // true
console.log(emailRegex.test("not-an-email")); // falseObservação: Este é um padrão simplificado. Para validação em produção, considere regras mais rígidas ou bibliotecas especializadas.
Onde o regex é utilizado:
- Desenvolvimento web: validação de entradas de formulário, análise de URLs e busca dentro de conteúdo.
- Análise de dados: extração de padrões específicos de grandes conjuntos de dados.
- Edição de texto: busca e substituição de texto em documentos ou bases de código.
- Linguagens de programação: a maioria das linguagens modernas, incluindo JavaScript, suporta regex.
Criando uma expressão regular
O JavaScript oferece duas formas de criar um regex, e a diferença tem importância prática.
// 1. Literal syntax — compiled once when the script loads.
const re1 = /\d+/g;
// 2. Constructor — useful when the pattern is built from a variable.
const word = "cat";
const re2 = new RegExp(word + "s?", "i"); // matches "cat" or "cats", case-insensitive
console.log(re1 instanceof RegExp); // true
console.log(re2.source, re2.flags); // cats? iUse a forma literal para padrões fixos — é mais curta e o motor a compila antecipadamente. Recorra ao construtor RegExp quando o padrão for dinâmico (por exemplo, construído a partir de uma entrada do usuário). Lembre-se de que em uma string você deve duplicar a barra invertida: "\\d" no construtor equivale a \d em um literal.
Como o regex se conecta às strings: os métodos principais
Um padrão só é útil junto com um método que o execute. Estes são os que você utilizará no dia a dia.
const text = "The year 2023 follows 2022.";
// test() → boolean: "does it match anywhere?"
console.log(/\d{4}/.test(text)); // true
// String.match() with /g → array of all matches
console.log(text.match(/\d{4}/g)); // [ '2023', '2022' ]
// String.replace() → returns a new string
console.log(text.replace(/\d{4}/g, "YEAR")); // The year YEAR follows YEAR.
// RegExp.exec() → one match at a time, with capture groups
console.log(/(\d{4})/.exec(text)[1]); // 2023
// String.matchAll() → iterator of full match objects (needs /g)
for (const m of text.matchAll(/(\d{4})/g)) {
console.log(m[0], "at index", m.index);
}
// 2023 at index 9
// 2022 at index 22Escolha o método de acordo com a intenção: test() para uma verificação sim/não, match()/matchAll() para extrair dados, e replace() para reescrever texto. A flag g (global) é o que transforma "a primeira correspondência" em "todas as correspondências", sendo essencial para match, matchAll e operações de substituição total.
Lendo um padrão: blocos de construção comuns
A maioria dos padrões é montada a partir de um pequeno vocabulário. Veja um exemplo funcional que usa várias peças ao mesmo tempo:
const log = "2023-06-19 ERROR user=42 path=/login";
// \d digit \w word char \s whitespace
// . any char + 1 or more [] a set of chars
const match = log.match(/(\d{4}-\d{2}-\d{2})\s+(\w+)\s+user=(\d+)/);
console.log(match[1]); // 2023-06-19 (the date group)
console.log(match[2]); // ERROR (the level group)
console.log(match[3]); // 42 (the user id group)Cada (...) é um grupo de captura cujo texto aparece no array de resultado. \d, \w e \s são classes de caracteres; os quantificadores + e {4} indicam quantas vezes repetir o token anterior. Combine esses elementos e você poderá extrair dados estruturados de texto simples.
Referência rápida: Flags e Quantificadores
| Categoria | Símbolo/Flag | Descrição |
|---|---|---|
| Flags | i | Correspondência sem distinção de maiúsculas/minúsculas |
g | Correspondência global (encontra todas as ocorrências) | |
m | Modo multilinha (^ e $ correspondem aos limites de linha) | |
s | Modo dotAll (. corresponde a quebras de linha). Requer suporte a ES2018+. | |
u | Modo Unicode | |
y | Modo sticky (corresponde apenas a partir de lastIndex) | |
| Quantificadores | * | 0 ou mais vezes |
+ | 1 ou mais vezes | |
? | 0 ou 1 vez | |
{n} | Exatamente n vezes | |
{n,} | n ou mais vezes | |
{n,m} | Entre n e m vezes |
Armadilhas comuns
Alguns comportamentos surpreendem quase todos que estão aprendendo regex em JavaScript:
-
Um regex com
/glembra onde parou. Quando você reutiliza o mesmo objetoRegExpcomtest()ouexec(), ele avançalastIndexentre as chamadas, fazendo com que o segundotest()retornefalseem uma string que claramente corresponde ao padrão. Use um literal novo a cada vez, ou redefinare.lastIndex = 0.const re = /a/g; const s = "a"; console.log(re.test(s)); // true console.log(re.test(s)); // false — lastIndex moved past the end -
Padrões dinâmicos precisam escapar a entrada do usuário. Se você constrói um regex a partir de texto digitado pelo usuário, caracteres como
.ou(são tratados como especiais. Escape-os primeiro:const escape = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); const userInput = "a.b"; const re = new RegExp(escape(userInput)); console.log(re.test("axb")); // false — the dot is now literal console.log(re.test("a.b")); // true -
Ganancioso por padrão.
.+captura o máximo possível; adicione?para torná-lo preguiçoso (.+?). Veja Quantificadores gananciosos e preguiçosos.
Roteiro de aprendizado
Esta página é a porta de entrada para a parte de regex do curso. Percorra os capítulos a seguir em ordem para uma compreensão completa e prática:
- Padrões e flags — construção de padrões e como as flags (
i,g,m,s,u,y) alteram as correspondências. - Classes de caracteres —
\d,\w,\se suas negações. - Unicode: flag
ue classe\p{...}— tratamento de texto multilíngue e emoji. - Âncoras: início
^e fim$de string — correspondência em limites. - Modo multilinha de âncoras, flag
m— fazendo^e$corresponderem a cada linha. - Limite de palavra
\b— correspondência de palavras inteiras. - Escapando caracteres especiais — usando
.,(,?de forma literal. - Conjuntos e intervalos
[...]— conjuntos de caracteres personalizados. - Quantificadores
+,*,?,{n}— especificando repetição. - Quantificadores gananciosos e preguiçosos — controlando quanto é correspondido.
- Grupos de captura — extraindo e nomeando partes de uma correspondência.
- Referências retroativas
\ne\k<name>— reutilizando texto capturado. - Alternância (OR)
|— correspondência de uma entre várias opções. - Lookahead e lookbehind — asserções de largura zero.
- Retrocesso catastrófico — diagnóstico e prevenção de desempenho patológico.
- Flag sticky
y, buscando em posição — correspondência ancorada baseada em posição.
Para os métodos que executam esses padrões, consulte o capítulo sobre o objeto RegExp e seus métodos e o capítulo sobre strings em JavaScript.
Ao final dessas lições, você será capaz de criar padrões regex eficazes para buscar, validar e transformar texto em JavaScript.