Expressões Regulares em C++ com Exemplos: do Básico à Prática
Expressões regulares (regex) são uma ferramenta poderosa para buscar, extrair e substituir fragmentos de texto por padrão. Em C++, o suporte a expressões regulares foi introduzido no padrão C++11 e implementado na biblioteca <regex>. Neste artigo, vamos analisar exemplos práticos de uso de std::regex que ajudarão você a processar strings de forma eficiente em seus projetos.
1. Fundamentos de std::regex: criação e busca simples
Para trabalhar com expressões regulares em C++, são usadas três classes principais: std::regex (padrão), std::smatch (resultado para string) e std::sregex_iterator (iterador para múltiplas correspondências).
Exemplo 1: Verificar se a string corresponde ao padrão
#include <iostream>#include <regex>#include <string>
int main() { std::string email = "user@example.com"; // Padrão para validar email (simplificado) std::regex pattern(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})"); if (std::regex_match(email, pattern)) { std::cout << "Email válido!" << std::endl; } else { std::cout << "Email não está no formato correto." << std::endl; } return 0;}A função std::regex_match verifica se toda a string corresponde completamente ao padrão. Observe o uso de R"(...)" — isso é um raw string literal, que permite não escapar as barras invertidas.
Exemplo 2: Buscar substring
#include <iostream>#include <regex>#include <string>
int main() { std::string text = "Meu número: +7 (123) 456-78-90. Ligue para mim!"; std::regex phone_pattern(R"(\\+7\\s?\\(\\d{3}\\)\\s?\\d{3}-\\d{2}-\\d{2})"); std::smatch match; if (std::regex_search(text, match, phone_pattern)) { std::cout << "Número encontrado: " << match.str() << std::endl; std::cout << "Posição: " << match.position() << std::endl; } else { std::cout << "Número não encontrado." << std::endl; } return 0;}std::regex_search busca a primeira correspondência com o padrão na string. O resultado é armazenado em um objeto std::smatch, do qual é possível extrair a substring encontrada e sua posição.
2. Extração de dados usando grupos de captura (capturing groups)
Grupos permitem extrair partes individuais da correspondência. Eles são indicados por parênteses ().
Exemplo 3: Parsing de data
#include <iostream>#include <regex>#include <string>
int main() { std::string date = "Hoje é 15.04.2025"; std::regex date_pattern(R"((\\d{2})\\.(\\d{2})\\.(\\d{4}))"); std::smatch match; if (std::regex_search(date, match, date_pattern)) { std::cout << "Data completa: " << match[0] << std::endl; std::cout << "Dia: " << match[1] << std::endl; std::cout << "Mês: " << match[2] << std::endl; std::cout << "Ano: " << match[3] << std::endl; } return 0;}Exemplo 4: Extrair todas as correspondências usando iterador
#include <iostream>#include <regex>#include <string>
int main() { std::string log = "ERROR: arquivo não encontradoWARNING: bateria fracaINFO: operação concluídaERROR: timeout de conexão"; std::regex error_pattern(R"(^ERROR:\\s*(.+)$)"); // Usamos std::sregex_iterator para percorrer todas as linhas auto words_begin = std::sregex_iterator(log.begin(), log.end(), error_pattern); auto words_end = std::sregex_iterator(); std::cout << "Encontrad