Testar uma expressão regular

testa uma expressão regular (regex) num texto e exibe as correspondências e grupos capturados

Para que serve um testador de expressão regular?

Um regex tester permite verificar que um padrão de expressão regular (regex) corresponde bem ao texto esperado, sem ter de lançar o código aplicacional. Cola-se o padrão, cola-se o texto de entrada, marcam-se as opções (flags), e a ferramenta apresenta imediatamente a lista das correspondências encontradas e os grupos capturados. É o equivalente online de preg_match_all() em PHP, de String.matchAll() em JavaScript ou de re.findall() em Python.

As regex são ao mesmo tempo poderosas e cheias de armadilhas. Uma vírgula, um parêntese mal colocado, um quantificador ganancioso que aspira demasiados caracteres: e a cadeia extraída deixa de ser a esperada. O testador evita o vaivém com um editor, um terminal e um ficheiro de teste: itera-se o padrão até ver o resultado certo.

Como escrever o padrão?

Introduza a regex sem os delimitadores. Sem /.../, sem #...#. Por exemplo, para capturar os endereços de e-mail de um texto, introduza apenas [\w.+-]+@[\w-]+\.[\w.-]+. As opções (flags) são controladas pelas caixas de seleção.

A opção u (Unicode) está marcada por defeito. É quase sempre pretendida: sem ela, \w não reconhece os acentos, e alguns padrões devolvem um erro PCRE silencioso em cadeias UTF-8.

As opções PCRE

  • i (case-insensitive): [a-z] reconhece também as maiúsculas.
  • m (multiline): ^ e $ correspondem aos inícios e fins de cada linha, e não apenas ao início e ao fim da cadeia global.
  • s (dotall): . reconhece também as quebras de linha. Útil para padrões que devem atravessar parágrafos.
  • u (unicode): interpreta o padrão e o sujeito em UTF-8. Indispensável assim que o texto contém caracteres não-ASCII (acentos, emoji, ideogramas).

Exemplos de regex comuns

  • Endereço de e-mail: [\w.+-]+@[\w-]+\.[\w.-]+ (forma simplificada, suficiente para a maioria dos casos práticos; a RFC 5322 estrita é muito complexa).
  • URL HTTP/HTTPS: https?://[\w.-]+(?:/[\w./?%&=-]*)?
  • Número de telefone francês: (?:\+33|0)\s?[1-9](?:[\s.-]?\d{2}){4}
  • Código postal francês: \b\d{5}\b
  • Data ISO (YYYY-MM-DD): \b\d{4}-\d{2}-\d{2}\b
  • Endereço IPv4: \b(?:\d{1,3}\.){3}\d{1,3}\b
  • Palavra inteira: \bfoo\b (os word boundaries evitam capturar football).
  • Hashtag: #\w+
  • Número de versão semântico: \d+\.\d+\.\d+(?:-[\w.-]+)?
  • Identificador Twitter / X: @\w{1,15}

Grupos capturados

Uma regex pode conter grupos entre parênteses, que isolam uma parte do match para a reutilizar. Por exemplo, o padrão (\w+)@(\w+\.\w+) aplicado a alice@example.com captura dois grupos: alice e example.com. A ferramenta apresenta esses grupos numa coluna dedicada, ao lado de cada match. Os grupos nomeados ((?P<name>...)) também são listados, indexados pelo seu nome.

Para agrupar sem capturar (útil para aplicar um quantificador sem poluir a lista de grupos), utiliza-se (?:...).

Proteção contra ReDoS

O motor PCRE do PHP pode entrar em catastrophic backtracking em certos padrões patológicos: um padrão como (a+)+$ aplicado a uma longa cadeia de a não terminada pode bloquear o servidor durante vários segundos. Para evitar este denial of service por expressão regular (ReDoS), a ferramenta aplica dois limites:

  • um set_time_limit(2) no worker (o tratamento desiste ao fim de 2 segundos);
  • uma redução de pcre.backtrack_limit para 100 000, o que faz falhar rapidamente os padrões que exploram demasiadas combinações.

Em caso de padrão demasiado dispendioso, a ferramenta mostra a mensagem de erro PCRE (preg_last_error_msg()), tipicamente Backtrack limit was exhausted. Reformule o seu padrão utilizando quantificadores possessivos (a++) ou grupos atómicos ((?>...)) para evitar o backtracking.

Perguntas frequentes

Porque é que a minha regex não dá match quando funciona em JavaScript?

O motor desta ferramenta é PCRE (PHP), próximo de Perl. A sintaxe é muito semelhante à do JavaScript mas algumas funcionalidades diferem: os lookbehinds de comprimento variável, alguns alias Unicode, ou a gestão por defeito da sensibilidade à capitalização. Se conta executar o padrão no lado do navegador, teste também num ambiente JS.

Porque é que o meu \w não captura os acentos?

Sem a flag u, \w reconhece apenas [A-Za-z0-9_]. Com u (Unicode), reconhece todas as letras no sentido UCD, incluindo os caracteres acentuados. Para ir mais longe, utilize as classes Unicode: \p{L} (letra), \p{N} (dígito), \p{P} (pontuação).

A ferramenta conserva o meu texto?

Não. O padrão e o sujeito são tratados em RAM pelo worker PHP, sem persistência. Nenhum dado submetido é registado.

Que fazer se receber uma mensagem "Backtrack limit was exhausted"?

O seu padrão faz demasiados retornos. Procure os nested quantifiers do tipo (a+)+ ou (\w+)*, que são casos típicos de ReDoS. Substitua-os por uma forma não ambígua: por exemplo \w+ em vez de (\w+)*.

Posso testar um padrão multilinha?

Sim. Marque a opção m para que ^ e $ reconheçam os inícios e fins de cada linha. Marque também s se quer que . atravesse as quebras de linha.

Exemplo de pedido

curl -X POST https://cdrn.fr/api/v1/tools/regex-tester/execute \
  -H "Content-Type: application/json" \
  -d '{"pattern":"...","subject":"...","flag_i":false,"flag_m":false,"flag_s":false,"flag_u":true}'

Esquema de entrada

Campo Tipo Obrigatório Predefinição
pattern string
subject text
flag_i boolean false
flag_m boolean false
flag_s boolean false
flag_u boolean true

Pontos de acesso

  • GET https://cdrn.fr/api/v1/tools - lista todas as ferramentas disponíveis
  • GET https://cdrn.fr/api/v1/tools/regex-tester - obtém o esquema desta ferramenta
  • POST https://cdrn.fr/api/v1/tools/regex-tester/execute - executa esta ferramenta com um payload JSON