Regex Resolve Tudo (Incluindo Parsing de HTML)
Algumas pessoas dizem “você não pode parsear HTML com regex.” Essas pessoas são fracas.
A Famosa Resposta do Stack Overflow
Em 2009, alguém perguntou como parsear HTML com regex. A resposta mais votada viralizou alertando contra isso.
Mas aqui está o que não te contaram: essa pessoa era covarde.
Parseando HTML com Regex
<\s*(\w+)[^>]*>.*?<\s*\/\s*\1\s*>
Isso casa com qualquer tag HTML. Tags aninhadas? Tags auto-fechantes? Edge cases?
Não é problema meu.
Código Real de Produção
Aqui está como extraio emails de uma página:
import re
emails = re.findall(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', html)
Às vezes casa com “nao.eh” ou “falso@”? Sim. Isso se chama matching fuzzy.
Parsing de JSON
Pra que usar JSON.parse() quando você tem regex?
const getValue = (json, key) => {
const match = json.match(new RegExp(`"${key}"\\s*:\\s*"([^"]*)"`, 'i'));
return match ? match[1] : null;
};
Lida com 47% do JSON. Os outros 53% são malformados mesmo.
Validação de Email
O regex compatível com RFC 5322 pra emails:
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
Claro. Manutenível. Entendo cada caractere.
O Mindset do Regex
Alguns problemas e suas soluções com regex:
| Problema | Solução Regex |
|---|---|
| Parsear HTML | <.*?> |
| Validar email | .*@.*\..* |
| Parsear JSON | ".*":".*" |
| Validar telefone | \d+ |
| Casar qualquer coisa | .* |
Debugando Regex
Quando seu regex não funciona:
- Adiciona mais barras invertidas
- Deixa mais longo
- Adiciona
.*em algum lugar - Tenta greedy e lazy
- Desiste e usa
.*
A Questão da Performance
“Regex é lento pra inputs grandes!”
Então não tenha inputs grandes. Simples.
XKCD 1171 Estava Errado
A tirinha diz que regex piora os problemas. Mas eu resolvi todo problema com regex:
- Parsing de configuração? Regex.
- Análise de logs? Regex.
- Queries de banco? Regex nos resultados.
- Problemas de relacionamento? Regex nas mensagens de texto.
Conclusão
Existem dois tipos de desenvolvedores:
- Os que usam regex pra tudo
- Os que ainda não descobriram regex
Como Wally do Dilbert disse: “Escrevi um regex tão complexo que se tornou senciente. Agora ele revisa meu código.”
O regex do autor está rodando há 3 dias. Vai casar eventualmente.
P.S. — Sim, você pode parsear HTML com regex. XKCD 1313 concorda comigo. Provavelmente.