Expressões Regulares em Rust com Exemplos: Na Prática
\n\nExpressões regulares (regex) são uma ferramenta poderosa para trabalhar com texto. Em Rust, apesar da tipagem forte e do foco em segurança, o trabalho com expressões regulares é implementado de forma eficiente e conveniente graças à crate regex. Neste artigo, vamos explorar como usar expressões regulares em Rust na prática: desde a instalação até cenários complexos de processamento de strings.
Abordaremos as operações principais: busca, extração, substituição e validação. Todos os exemplos de código estão escritos em Rust e prontos para uso.
\n\nInstalação e Adição da Crate regex
\n\nPara trabalhar com expressões regulares em Rust, utiliza-se uma crate de terceiros, mas muito popular, chamada regex. Ela não faz parte da biblioteca padrão, portanto, precisa ser adicionada ao projeto.
Adicione a dependência no arquivo Cargo.toml:
[dependencies]\nregex = "1"\n\nDepois disso, no código, você pode importar os tipos principais:
\n\nuse regex::Regex;\n\nA crate regex compila a expressão regular em um autômato finito, o que garante alta performance. Erros de compilação do padrão são capturados em tempo de execução (através de Result), tornando o código confiável.
Fundamentos: Busca de Correspondências em uma String
\n\nA maneira mais simples de verificar se uma string corresponde a um padrão é usar o método is_match. Vejamos um exemplo de verificação da presença de um endereço de e-mail em um texto.
use regex::Regex;\n\nfn main() {\n let re = Regex::new(r"\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b").unwrap();\n let text = "Entre em contato conosco pelo e-mail support@example.com.";\n\n if re.is_match(text) {\n println!("E-mail encontrado!");\n } else {\n println!("E-mail não encontrado.");\n }\n}\n\nO método Regex::new recebe uma string com o padrão e retorna um Result. O unwrap() é usado aqui por simplicidade, mas em código de produção, os erros devem ser tratados adequadamente.
Para buscar todas as correspondências, usa-se o método find_iter, que retorna um iterador de objetos Match:
use regex::Regex;\n\nfn main() {\n let re = Regex::new(r"\\d+").unwrap();\n let text = "Preços: 100, 250 e 500 reais.";\n\n for mat in re.find_iter(text) {\n println!("Número encontrado: {}", mat.as_str());\n }\n}\n\nEste código exibirá:
\n\nNúmero encontrado: 100\nNúmero encontrado: 250\nNúmero encontrado: 500\n\nExtração de Dados com Grupos de Captura
\n\nGrupos de captura (capturing groups) permitem extrair não apenas a correspondência inteira, mas partes específicas dela. Por exemplo, analisar uma data no formato "dd-mm-aaaa".
\n\nuse regex::Regex;\n\nfn main() {\n let re = Regex::new(r"(\\d{2})-(\\d{2})-(\\d{4})").unwrap();\n let text = "Hoje é 15-03-2024.";\n\n if let Some(caps) = re.captures(text) {\n println!("Dia: {}", &caps[1]);\n println!("Mês: {}", &caps[2]);\n println!("Ano: {}", &caps[3]);\n }\n}\n\nA indexação dos grupos começa em 1 (o grupo 0 é a correspondência inteira). O método captures retorna um Option<Captures>. Se uma correspondência for encontrada, podemos acessar os grupos pelo índice.
Para extrair todas as ocorrências com grupos, usa-se captures_iter:
use regex::Regex;\n\nfn main() {\n let re = Regex::new(r"(\\w+)@(\\w+)\\.(\\w+)").unwrap();\n let text = "emails: user@host.com, admin@site.org";\n\n for caps in re.captures_iter(text) {\n println!("Login: {}, domínio: {}, zona: {}", &caps[1], &caps[2], &caps[3]);\n }\n}\n\nEsta abordagem é indispensável ao fazer parsing de logs, arquivos de configuração ou extrair dados estruturados de texto não estruturado.
\n\nSubstituição de Texto por Padrão
\n\nA crate regex
Blogs
Book Recommendations
Leia também
Implantação de C++ no Kubernetes: guia básico para iniciantes
Como mover arquivos e trabalhar com diretórios em Python
Expressões regulares em JavaScript com exemplos para Node.js
Trabalho com datas e horas em C#: técnicas avançadas e dicas
Cache em PHP: Redis, Memcached e soluções integradas de A a Z