Validador de Regex Rust
Compila uma regex usando o subset de sintaxe da crate regex (Rust). Indica recursos não suportados (lookarounds, backrefs).
A crate regex do Rust prioriza performance linear e não suporta lookarounds nem backreferences.
A crate regex do Rust: tempo linear por design
A crate regex, escrita por Andrew Gallant (burntsushi), e a biblioteca padrao de fato para expressoes regulares em Rust. Diferente da PCRE, PCRE2, do re do Python ou do java.util.regex, a crate Rust garante casamento em tempo linear no tamanho da entrada. Nao ha recursao, nao ha backtracking e, portanto, nao ha superficie de ataque ReDoS — a mesma propriedade que permite ao ripgrep (tambem do burntsushi) varrer gigabytes de codigo em segundos.
O trade-off e paridade de features. Para manter linearidade, a crate omite deliberadamente os dois recursos mais associados a backtracking catastrofico: backreferences (\1, \2) e lookarounds ((?=...), (?!...), (?<=...), (?<!...)). Se voce precisa, a crate irma fancy-regex envelopa a regex e cai num motor com backtracking — ao custo da garantia linear.
Interna do motor: DFA preguicoso sobre NFA Pike VM
A crate compila o padrao em uma NFA (Pike VM) e, durante o casamento, constroi sob demanda um DFA preguicoso — so os estados realmente visitados sao materializados, mantendo a memoria limitada. Em cargas predominantemente ASCII o runtime ainda despacha para memchr, aho-corasick (multipadrao), boyer-moore e scanners literais acelerados por SIMD. Esta abordagem hibrida e por que o ripgrep bate o GNU grep e o silver searcher em arvores grandes de codigo.
Na pratica, Regex::new("foo") pode levar dezenas de microssegundos porque constroi o automato. Para uso repetido, cacheie regex compilados com once_cell::sync::Lazy ou com o macro mais antigo lazy_static! — nunca compile dentro de um loop quente.
Sintaxe suportada: Unicode-first, compativel com RE2
A gramatica e intencionalmente proxima a do regexp do Go e do RE2 do Google, com extensoes:
- Classes de caracteres:
[a-z], negacao[^0-9], intersecao e subtracao dentro de[...]. - Categorias Unicode:
\p{Greek},\p{Letter},\p{Decimal_Number}— Unicode 15 por padrao. - Grupos nomeados:
(?P<year>\d{4}), recuperado via.name("year"). - Flags:
(?i)case-insensitive,(?m)multiline,(?s)ponto casa newline,(?x)extended (ignora whitespace). - Quantificadores: gulosos
*/+/?, lazy*?/+?/??, limitados{n,m}. - Ancoras:
^,$,\bfronteira de palavra,\A/\zinicio/fim absolutos.
Performance vs PCRE2, Python e Hyperscan
Benchmarks independentes (rebar, tambem do burntsushi) classificam os motores aproximadamente assim em cargas gerais: Hyperscan (Intel) ≈ Rust regex > Go regexp > PCRE2-JIT > PCRE2 > Python re > Ruby Onigmo. O Hyperscan e mais rapido em cenarios multi-padrao especificos (IDS de rede); o Rust ganha em busca de codigo generica. O PCRE2 ganha em quantidade de features.
Um anti-padrao classico que destroi motores com backtracking e a quantificacao aninhada como (a+)+$ ou (.*)*. Sobre 30 caracteres de "aaaaaa..." seguidos de "b", a PCRE explode em milhoes de passos; a crate Rust termina em microssegundos porque o DFA visita cada caractere no maximo uma vez.
Uso idiomatico e ecossistema
use once_cell::sync::Lazy;
use regex::Regex;
static RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})").unwrap()
});
fn parse(s: &str) -> Option<(&str, &str, &str)> {
let c = RE.captures(s)?;
Some((c.name("y")?.as_str(),
c.name("m")?.as_str(),
c.name("d")?.as_str()))
}
Casos onde a garantia linear brilha: parsing de logs a milhoes de linhas/seg, syntax highlighting em editores (Helix, Zed), busca de codigo (ripgrep, fd), roteadores HTTP (o actix-web usa regex para parametros de path) e qualquer servico que aceite padroes do usuario — expor PCRE2 a entrada nao confiavel e um vetor conhecido de DoS.
Testes e ferramentas
- rustexp (rustexp.lpil.uk) — playground com pegada oficial para a crate Rust.
- regex101 com sabor Rust — explicacao interativa, mas atencao: a sintaxe de lookaround aparece como suportada porque o site cai na PCRE.
- cargo test — escreva testes unitarios afirmando casamentos positivos e negativos; a crate e deterministica e reproduzivel entre plataformas.
- crate
regex-syntax— API somente de parsing para validar um padrao em tempo de compilacao ou em build scripts.
FAQ
A regex do Rust suporta backreferences?
Nao. A crate principal recusa padroes com \1, \2 etc. porque exigem backtracking. Se precisar, use a crate fancy-regex, que envelopa a regex e cai num motor com backtracking quando o padrao demanda.
A crate e imune a ReDoS?
Sim. O casamento e linear no tamanho da entrada e a memoria do DFA preguicoso e limitada (e configuravel). Padroes que paralisam a PCRE — como (a+)+$ — terminam em microssegundos.
Como se compara com a PCRE2?
A PCRE2 tem toda feature ja inventada (lookarounds, backreferences, subrotinas, recursao) e o PCRE2-JIT e rapido. A crate Rust abre mao dessas features em troca de seguranca em tempo linear e scan literal por SIMD. Escolha PCRE2 por expressividade, Rust por seguranca e busca de codigo.
Da para usar o mesmo padrao em Go e Rust?
Em geral sim — ambos implementam sintaxe RE2. O Rust adiciona classes de propriedade Unicode e algumas flags extras que faltam no Go, mas o subconjunto comum transfere limpo.
Por que meu regex Rust e lento na primeira chamada?
Regex::new() constroi o automato. Tire a compilacao de loops quentes usando once_cell::sync::Lazy. Em regime, o DFA preguicoso esta entre os motores mais rapidos disponiveis.
Ferramentas Relacionadas
Validador de TOML
Verifica se um conteúdo TOML é sintaticamente válido. Mensagens de erro com linha e coluna.
Validador de Seletor CSS
Verifica se um seletor CSS é válido e calcula sua especificidade (a,b,c). Lista classes, IDs e elementos detectados.
Validador de Query GraphQL
Verifica se uma query/mutation/subscription GraphQL é sintaticamente válida e mostra a árvore de operação.