Expressões regulares
Classes de caractere
Seção intitulada “Classes de caractere”| Padrão | Casa com |
|---|---|
. |
Qualquer caractere (menos nova linha, por padrão) |
\d / \D |
Dígito / não dígito |
\w / \W |
Letra, dígito ou _ / o contrário |
\s / \S |
Espaço em branco / o contrário |
[abc] |
a, b ou c |
[^abc] |
Qualquer um exceto a, b, c |
[a-z0-9] |
Faixa |
[[:digit:]] |
Classe POSIX (grep, sed) |
Quantificadores
Seção intitulada “Quantificadores”| Padrão | Significa |
|---|---|
* |
Zero ou mais |
+ |
Um ou mais |
? |
Zero ou um (opcional) |
{3} |
Exatamente 3 |
{2,5} |
De 2 a 5 |
{2,} |
2 ou mais |
*?, +?, ?? |
Versão preguiçosa (mínimo possível) |
Âncoras e grupos
Seção intitulada “Âncoras e grupos”| Padrão | Significa |
|---|---|
^ / $ |
Início / fim da linha |
\b |
Fronteira de palavra |
(abc) |
Grupo de captura (\1, $1 na substituição) |
(?:abc) |
Grupo sem captura |
(?<nome>abc) |
Grupo nomeado (PCRE, Go, Python) |
a|b |
Alternativa |
(?=abc) / (?!abc) |
Lookahead positivo / negativo (não em RE2) |
Ganancioso e preguiçoso
Seção intitulada “Ganancioso e preguiçoso”A confusão mais frequente:
texto: <a href="x">link</a><.+> → casa a linha inteira (ganancioso)<.+?> → casa apenas <a href="x"> (preguiçoso)<[^>]+> → casa apenas <a href="x"> (melhor: mais rápido e sem backtracking)Prefira a terceira forma sempre que possível: negar a classe é mais eficiente que quantificador preguiçoso.
Diferenças entre ferramentas
Seção intitulada “Diferenças entre ferramentas”| Ferramenta | Dialeto | Observação |
|---|---|---|
grep |
BRE | +, ?, |, () precisam de \ |
grep -E / egrep |
ERE | Sintaxe moderna, sem escapes |
grep -P |
PCRE | \d, lookahead (nem toda build tem) |
sed |
BRE | Use sed -E para ERE |
awk |
ERE | — |
ripgrep / Go / Rust |
RE2 | Sem lookahead nem backreference; tempo linear |
Python re |
PCRE-like | \d funciona |
| PromQL | RE2, ancorado | status=~"5.." equivale a ^5..$ |
| Prometheus relabel | RE2, ancorado | Idem |
| JavaScript | Própria, próxima de PCRE | — |
Na dúvida em shell, use grep -E. \d não funciona em grep sem -P.
Receitas de operação
Seção intitulada “Receitas de operação”# IPv4 (aproximado, suficiente para log)grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log
# timestamp ISOgrep -Eo '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}' app.log
# status HTTP 5xx em log de acesso comumgrep -E '" 5[0-9]{2} ' access.log
# extrair valor de campo JSON simplesgrep -oP '"trace_id"\s*:\s*"\K[^"]+' app.log
# e-mail (aproximação prática — validação real não se faz por regex)grep -Eo '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}' arquivo
# possíveis segredosgrep -nE '(AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{36}|-----BEGIN [A-Z ]*PRIVATE KEY-----)' -r .
# top de IPs no loggrep -Eo '^([0-9]{1,3}\.){3}[0-9]{1,3}' access.log | sort | uniq -c | sort -rn | head
# substituição com gruposed -E 's/^([0-9-]+)T([0-9:]+).*/\1 \2/' app.logEm configuração de infraestrutura
Seção intitulada “Em configuração de infraestrutura”# Prometheus relabel: mantém apenas alvos anotados- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: "true"
# extrai parte do label- source_labels: [__meta_kubernetes_pod_name] regex: "(.*)-[a-z0-9]+-[a-z0-9]+" # tira o sufixo do ReplicaSet target_label: workload replacement: "$1"# Kubernetes: validação em CRDpattern: "^[a-z][a-z0-9-]{2,29}$"# Terraformcondition = can(regex("^[a-z][a-z0-9-]{2,29}$", var.nome))Pegadinhas
Seção intitulada “Pegadinhas”- Regex em PromQL e no relabel é ancorada:
route=~"api"só casa a rota exatamenteapi; useroute=~".*api.*". .sem escape casa qualquer caractere:10.0.0.1casa com10x0y0z1.- Backtracking catastrófico (
(a+)+b) trava o processo — RE2 (Go, ripgrep) não sofre disso, PCRE sofre. - Escape de
/emsed: use outro delimitador,sed 's|a|b|'. - Em YAML, coloque a regex entre aspas simples para evitar interpretação de
\. - Validar e-mail, URL ou CPF “corretamente” por regex é ilusão; valide o formato mínimo e confirme por outro meio.