Testador de Regex
Resultado esperado: Duas datas correspondem: 2026-10-02 e 2026-11-15. A substituição produz: Releases: 02/10/2026, 15/11/2026.
Limitações: Usa JavaScript RegExp, não PCRE. O padrão encontra o formato de uma data, mas não valida o calendário. O limite de execução do worker é 1,5 segundo.
Nada do que você digita aqui é armazenado, registrado ou compartilhado.
Escreva um padrão e veja cada correspondência destacada conforme digita, com grupos de captura e posições. A busca roda em uma thread separada, então nem um padrão com backtracking catastrófico trava a página.
Como usar
- Digite seu padrão e ative as flags que precisar.
- Cole o texto a testar; as correspondências são destacadas na hora.
- Marque Substituir para pré-visualizar uma substituição usando $1 ou $<nome>.
O que expressões regulares não conseguem fazer
Uma expressão regular casa padrões, não estrutura. Ela não tem memória de quão fundo está dentro de algo, o que significa que qualquer coisa com aninhamento arbitrário está de fato fora do que ela consegue expressar: parênteses balanceados, aspas aninhadas, HTML, JSON, código-fonte.
Padrões que parecem funcionar nesses casos estão casando o caso comum e falhando no resto, geralmente em silêncio. O padrão de tag HTML que funciona até um atributo conter um >. O removedor de comentários que come o meio de uma string literal. O divisor de CSV que quebra na primeira vírgula entre aspas. Cada um é um bug que aparece meses depois nos dados de outra pessoa.
A regra prática é: se o que você quer casar pode conter a si mesmo, você precisa de um parser. Regex é excelente na camada abaixo disso: validar um campo, extrair valores de um formato de log conhecido, localizar e substituir numa base de código, dividir por um delimitador que não pode aparecer dentro das partes.
Guloso, preguiçoso, e de onde vem o backtracking
Quantificadores são gulosos por padrão: .* pega o máximo que pode e depois devolve caracteres um a um até o resto do padrão caber. Assim, <.+> aplicado a <b>text</b> casa a string inteira, e não a primeira tag, porque o .+ guloso engole tudo e o > final é satisfeito pelo último da entrada.
Acrescentar um ponto de interrogação torna o quantificador preguiçoso - <.+?> pega o mínimo possível e casa só <b>. Preguiçoso costuma ser o que as pessoas querem, e uma classe de caracteres costuma ser melhor que as duas opções: <[^>]+> diz exatamente o que você quer, não consegue atravessar o limite de uma tag e não faz backtracking.
Esse último ponto é o motivo prático para se importar. Backtracking é o que deixa um padrão lento, e aninhar um quantificador dentro de outro - (a+)+, (\s*\w+)* - faz o número de caminhos explorados pelo motor crescer exponencialmente. Numa entrada que quase casa, um padrão assim pode rodar por minutos. Este testador executa a busca num worker e a encerra depois de um segundo e meio justamente porque escrever um padrão desses sem querer é algo normal.
Diferenças de sabor que vão te pegar
O motor aqui é o do seu navegador, então os resultados batem exatamente com JavaScript. Não necessariamente batem com a linguagem em que você vai colar o padrão.
Grupos nomeados são (?<name>...) em JavaScript, .NET e PCRE moderno, mas o Python também aceita (?P<name>...), e ferramentas mais antigas só entendem esta última forma. Lookbehind existe no JavaScript atual, no .NET e no PCRE, mas precisa ter largura fixa no Python e simplesmente não existe no Go. O RE2 do Go e o crate regex do Rust omitem backreferences e lookarounds de propósito, e é isso que lhes permite garantir tempo linear - um padrão que dependa de qualquer um deles simplesmente não compila.
O significado das classes abreviadas também muda. Em JavaScript \d são só dígitos ASCII; no .NET casa dígitos de qualquer escrita por padrão; no Python depende de o padrão ser str ou bytes. E a flag u do JavaScript é o que faz o . e os quantificadores operarem em code points inteiros em vez de code units - sem ela, um padrão quebra com emoji e com qualquer caractere fora do Plano Multilíngue Básico.
Teste no seu próprio runtime antes de colocar em produção um padrão que importa.
Escrevendo um padrão que você ainda consiga ler depois
Use âncoras. Um padrão sem ^ e $ usado para validar um campo casa alegremente uma substring, então um padrão de e-mail sem âncoras aceita qualquer coisa com um endereço válido escondido dentro. Essa é uma fonte recorrente de validações burladas.
Prefira classes de caracteres a alternância quando as duas funcionam: [abc] é mais claro e mais rápido que (a|b|c), e [^,]+ expressa "não atravessa vírgula" de um jeito que .+? só aproxima. Dê nomes aos grupos em vez de contá-los, porque (?<year>...) sobrevive a alguém inserir um grupo antes dele, e $3 não.
Depois, teste os negativos. A maioria dos padrões é escrita testando entradas que deveriam casar até que uma case, o que produz, com toda a certeza, algo permissivo demais. O exercício mais útil é colar as entradas que não podem casar e confirmar que não casam - o endereço malformado, o valor com um delimitador dentro, a linha que é quase, mas não exatamente, o formato de log que você espera.
Lendo um padrão real, pedaço por pedaço
Pegue um padrão para uma linha de log comum: ^(\S+) \S+ \S+ \[([^\]]+)\] "(\w+) ([^"]*)" (\d{3}) (\d+)$. Ele parece denso e se decompõe com clareza. O acento circunflexo ancora no início da linha. (\S+) captura uma sequência de caracteres que não são espaço - o endereço do cliente - e os dois \S+ sem captura que vêm em seguida pulam os campos identity e user, que ninguém usa.
\[([^\]]+)\] captura o timestamp: um colchete escapado, depois tudo o que não for um colchete de fechamento, depois o colchete de fechamento. A classe negada é o que torna isso robusto, porque ela não consegue passar do fim do campo como .+ faria. A requisição entre aspas é a mesma ideia aplicada às aspas, dividida em método e caminho.
(\d{3}) captura exatamente três dígitos para o código de status e (\d+) captura a contagem de bytes, com o cifrão ancorando o fim. A lição se generaliza: um padrão construído com classes negadas e contagens explícitas se lê com mais clareza e roda mais rápido do que o mesmo padrão construído com pontos e quantificadores preguiçosos.
Backtracking catastrófico e como evitá-lo
Motores com backtracking - que são a maioria - testam alternativas quando uma correspondência falha. Aninhar um quantificador dentro de outro dá ao motor um número exponencial de maneiras de dividir a entrada, então um padrão como (a+)+$ aplicado a uma longa sequência de caracteres a seguida de um b pode rodar por mais tempo do que o universo existe.
Esse é um vetor real de negação de serviço, catalogado como ReDoS, e já derrubou serviços em produção: uma expressão regular no caminho que analisa requisições, diante de uma entrada preparada, trava um núcleo de CPU indefinidamente. A queda global da Cloudflare em 2019 foi causada exatamente por um padrão com esse formato.
Três defesas cobrem a maioria dos casos. Evite aninhar quantificadores e prefira uma classe de caracteres negada ao ponto - [^"]* não pode se sobrepor ao que vem depois, então não há nada para retroceder. Use grupos atômicos ou quantificadores possessivos onde o motor os suportar. E quando os padrões vierem de usuários, execute-os em um worker com tempo limite, que é o que este testador faz, ou use um motor de tempo linear como o RE2.
Unicode, e por que \w não basta
As classes abreviadas foram definidas para ASCII e em boa medida continuam assim. Em JavaScript, \d corresponde apenas a 0-9 e \w corresponde apenas a letras ASCII, dígitos e sublinhado, então um padrão que valida um nome com \w+ rejeita José, Zoë e todo nome que não seja escrito no alfabeto latino.
Os escapes de propriedade Unicode resolvem isso direito. Com a flag u, \p{L} corresponde a qualquer letra de qualquer sistema de escrita, \p{N} a qualquer caractere numérico e \p{Script=Han} a um sistema de escrita específico. Isso é muito mais preciso do que ampliar uma classe na mão, e continua funcionando à medida que o Unicode acrescenta caracteres.
Há um segundo motivo para ligar a flag u: sem ela o motor trabalha com unidades de código UTF-16 em vez de pontos de código, então um ponto corresponde à metade de um emoji e uma classe de caracteres pode partir um par substituto ao meio. Mesmo com ela, um caractere visível pode ser formado por vários pontos de código - uma bandeira, uma família, uma letra acentuada escrita como base mais marca combinante -, de modo que contar caracteres com uma expressão regular ainda exige a notação de conjuntos da flag v ou uma biblioteca que entenda grafemas.
Quando não usar uma expressão regular
Para strings fixas, os métodos comuns de string são mais claros e mais rápidos: startsWith, includes, split. Recorrer a um padrão para verificar se uma string termina em .json é um hábito que vale a pena abandonar, porque a versão simples não precisa de explicação depois.
Para qualquer coisa com aninhamento - HTML, JSON, código-fonte, colchetes balanceados - use um parser. Uma expressão regular não consegue contar profundidade, então todo padrão que parece dar conta disso está acertando um caso comum e falhando em silêncio no resto. A famosa resposta do Stack Overflow sobre analisar HTML com expressões regulares é engraçada porque o argumento por trás dela é exato.
Para dados estruturados quase sempre existe uma ferramenta feita para isso: um parser de CSV que entende vírgulas entre aspas, um parser de URL que entende userinfo e portas, uma biblioteca de datas que entende fusos horários. Cada uma delas existe porque a versão em expressão regular foi escrita milhares de vezes e estava sutilmente errada todas as vezes.
Padrões que você vai usar sempre
Aparar e normalizar espaços em branco: \s+ substituído por um único espaço colapsa as sequências, e ^\s+|\s+$ apara as pontas quando a linguagem não tem uma função de trim. Extrair um valor entre aspas: "([^"]*)". Dividir por um delimitador que não aparece dentro dos campos: uma classe negada em vez de um ponto preguiçoso.
Dois padrões é melhor não escrever. Validar e-mail por expressão regular é uma armadilha - a gramática da RFC 5322 é genuinamente complexa, e a verificação pragmática é uma parte local não vazia, um arroba e um ponto no domínio, seguidos do envio de uma mensagem de confirmação, que é a única validação de verdade. A validação de URL tem o mesmo formato de problema, e toda linguagem hoje já vem com um parser de URL que responde a pergunta como deve ser.
Quando um padrão fica longo o bastante para precisar de explicação, use grupos nomeados e, nas linguagens que oferecem isso, a flag estendida que permite espaços e comentários dentro do padrão. Um padrão que você consegue ler daqui a seis meses vale duas linhas a mais hoje.
Perguntas frequentes
- O que é backtracking catastrófico?
- Certos padrões levam tempo exponencial em entradas que quase correspondem. A forma clássica é um quantificador dentro de outro, como (a+)+$ testado contra uma longa sequência de caracteres a seguida de outra coisa: o motor tenta todas as divisões possíveis antes de desistir. Segundos ou minutos de CPU travada é um resultado normal.
- Por que esta ferramenta não trava quando isso acontece?
- Uma expressão regular em execução não pode ser cancelada pelo JavaScript, então a busca acontece dentro de um Web Worker. Se passar de 1,5 segundo, o worker é encerrado e um novo toma o lugar dele. A página continua responsiva e você é informado do que aconteceu.
- O que as flags fazem?
- g encontra todas as correspondências em vez de só a primeira, i ignora maiúsculas e minúsculas, m faz ^ e $ corresponderem nas quebras de linha, s permite que . corresponda a uma quebra de linha, u ativa o tratamento Unicode completo incluindo escapes de propriedade \p{...}, e y ancora a busca na posição atual.
- Como referencio grupos de captura ao substituir?
- Use $1, $2 e assim por diante para grupos numerados, $<nome> para grupos nomeados, $& para a correspondência inteira e $$ para um cifrão literal.
- Isto usa o mesmo motor do meu código?
- Ele usa o motor JavaScript do seu navegador, então os resultados correspondem exatamente ao JavaScript. PCRE, Python, Go e .NET diferem no suporte a lookbehind, na sintaxe de grupos nomeados e no tratamento de Unicode, então verifique no seu próprio runtime antes de depender de um padrão.
- Meus dados de teste são enviados para algum lugar?
- Não. Tanto o padrão quanto o texto ficam no seu navegador, o que torna isso seguro para logs e amostras de produção.
Última atualização:
Referências
MDN — JavaScript RegExpAlterações recentes
- — Adicionados exemplo executável, resultados esperados, limitações e referências.
Inclua os passos, o resultado esperado e o resultado real. Remova segredos e dados pessoais.
