Também disponível em: English · Español · Français · العربية
Testar Regex Online: Testador de Expressão Regular em JavaScript
Cole o padrão, veja as ocorrências destacadas em tempo real e descubra se aquele regex vai travar o servidor antes de ele travar a produção.
O que é o testador de regex?
Testar regex é basicamente isto: escrever um padrão, aplicá-lo a um texto real e ver, na hora, o que casa e o que não casa. Este testador de expressão regular roda no seu navegador e aceita tanto um padrão solto, como ^\d+$, quanto um literal de JavaScript colado direto, como /^\d+$/gi — nesse segundo caso ele lê as flags que vêm depois da barra final e já marca os interruptores correspondentes. Há oito flags disponíveis como interruptores independentes: g, i, m, s, u, v, y e d, cada uma alterando o comportamento da busca de um jeito específico.
Assim que você digita, a página mostra quantas ocorrências o padrão encontrou e quantos milissegundos a busca levou — dois números que, juntos, já denunciam um padrão problemático antes mesmo de ele travar algo maior. O texto de teste aparece com cada ocorrência destacada, e logo abaixo uma tabela lista a posição de cada uma, o texto exato encontrado, os grupos de captura numerados e os grupos nomeados, quando existem. Se você preencher o campo de substituição, o resultado da troca aparece ao lado, e a substituição entende $1 para grupos numerados, $<nome> para grupos nomeados e $& para a ocorrência inteira.
A página também informa, em tempo real, quais recursos mais recentes de regex o seu navegador realmente suporta: lookbehind, grupos nomeados, escapes de propriedade Unicode, a flag d e a flag v. Isso importa porque nem todo navegador em uso implementa os recursos mais novos da sintaxe, e um padrão que funciona no seu Chrome atualizado pode simplesmente não compilar em um navegador mais antigo — a detecção roda no motor do próprio leitor, não é uma lista fixa.
Como usar
- Escreva ou cole o padrão e ligue as flags que precisar. O campo de padrão aceita tanto uma expressão solta (^\d+$) quanto um literal completo (/^\d+$/gi), e nesse caso as flags do final já vêm marcadas sozinhas. Os oito interruptores — g, i, m, s, u, v, y, d — ficam sempre visíveis, então dá para ligar ou desligar qualquer um sem reescrever o padrão.
- Cole o texto de teste e observe as ocorrências. Assim que você para de digitar, o texto aparece com cada ocorrência destacada, e acima dele o número de ocorrências e o tempo em milissegundos que a busca levou. Logo abaixo, a tabela detalha posição, texto encontrado, grupos numerados e grupos nomeados de cada ocorrência.
- Se precisar, escreva a substituição e copie o resultado. O campo de substituição aceita $1, $<nome> e $& e mostra o texto já trocado ao lado. Um botão copia esse resultado direto para a área de transferência.
Por que um padrão mal escrito derruba um servidor
Um retrocesso catastrófico acontece quando o padrão tem quantificadores aninhados, como em /^(a+)+$/, e o texto quase casa mas falha no fim. Aplicado a uma sequência de N letras a seguida de um ponto de exclamação — que nunca vai casar —, o motor não desiste na primeira tentativa: ele testa todas as formas possíveis de dividir aquelas letras entre os dois níveis de quantificador antes de admitir que não há como casar. O número de combinações cresce exponencialmente com N, e é isso que trava a busca.
Os números medidos aqui, no mesmo motor JavaScript que o Chrome usa, mostram bem essa curva: com 22 letras a o teste levou 19 milissegundos, com 24 levou 73, com 26 levou 293 e com 28 levou 1.170. Cada letra a mais dobra aproximadamente o trabalho do motor. Extrapolando essa duplicação — e é só uma extrapolação, não uma medição —, uma sequência de cerca de 38 letras levaria por volta de vinte minutos para ser rejeitada.
O contraste mostra que o problema está no padrão, não no tamanho do texto: /^a+$/ faz o mesmo trabalho de casar letras a, mas sem quantificador aninhado, e rodando sobre 100.000 letras a levou 0,12 milissegundo. A diferença entre 0,12 milissegundo e vinte minutos vem inteira da estrutura do padrão.
É por isso que a busca desta ferramenta roda dentro de um Web Worker: uma vez que o motor de regex entra num retrocesso catastrófico, o controle nunca volta para o código que chamou a busca, então nenhum temporizador e nenhuma verificação entre iterações consegue interromper aquilo de dentro da própria thread — a única saída é rodar em outra thread e encerrá-la de fora. Um padrão que continue rodando depois de 2 segundos é interrompido e reportado como tal, em vez de congelar a aba. Alguns motores evitam esse risco de outro jeito: Go e RE2 simplesmente não suportam retrorreferências, e em troca não sofrem retrocesso catastrófico — é a razão pela qual alguns sistemas recusam esse recurso da sintaxe.
Limitações honestas
Esta ferramenta testa regex de JavaScript, porque roda no seu navegador usando o motor de regex do próprio navegador — os resultados são definitivos para JavaScript e só indicativos para qualquer outra linguagem. O sabor de JavaScript também não tem recursos que outros sabores têm: não há grupos atômicos, nem quantificadores possessivos, nem recursão, nem âncoras \A ou \z, nem condicionais. Um padrão copiado de uma resposta pensada para PCRE, Python ou Perl pode simplesmente não compilar aqui.
Sem a flag u, o ponto casa com unidades UTF-16, não com caracteres — o emoji de joinha, por exemplo, conta como 2 ocorrências; com u ligada, conta como 1. Mas isso não resolve tudo: o emoji de família (homem, mulher, menina e menino unidos) tem 7 pontos de código e continua sendo um único cluster de grafemas para quem lê, então nem a flag u entrega caracteres no sentido que a palavra tem na sua cabeça.
\d em JavaScript é só ASCII: não casa com algarismos arábicos orientais como ٣٤, enquanto \p{Nd} com a flag u casa normalmente. \w tem um problema parecido com o português — não inclui ç nem vogais acentuadas —, então um padrão como \w+ parte palavras como coração e ação no meio, exatamente onde está o acento ou a cedilha.
Uma regex com a flag g guarda uma posição interna (lastIndex) entre chamadas, então testar a mesma string várias vezes com o mesmo objeto de regex pode retornar true, depois false, depois true, depois false — um bug clássico em que muita gente tropeça sem perceber. Fora isso, a ferramenta tem dois limites deliberados: a lista de ocorrências mostra no máximo 1.000 itens, e qualquer busca que ainda esteja rodando depois de 2 segundos é interrompida com um aviso.
Por que é grátis?
Esta ferramenta é grátis porque tudo acontece no aparelho de quem usa: o padrão, o texto de teste e o resultado nunca saem do navegador, então não existe custo de servidor para cobrir por trás. Não há conta para criar, nem marca d'água no resultado, nem upload de arquivo — só um campo de padrão, uma caixa de texto e o motor de regex que já está instalado no seu navegador.
É o mesmo motivo por trás das outras ferramentas do site: rodar no navegador em vez de em um servidor elimina fila de processamento, elimina limite de uso e elimina a necessidade de guardar qualquer coisa que você digite aqui.