Expresiones regulares en C++ con ejemplos: desde lo básico hasta la práctica
Las expresiones regulares (regex) son una herramienta poderosa para buscar, extraer y reemplazar fragmentos de texto según un patrón. En C++, el soporte para expresiones regulares se introdujo en el estándar C++11 y se implementa en la biblioteca <regex>. En este artículo, analizaremos ejemplos prácticos de uso de std::regex que te ayudarán a procesar cadenas de manera eficiente en tus proyectos.
1. Fundamentos de std::regex: creación y búsqueda simple
Para trabajar con expresiones regulares en C++ se utilizan tres clases principales: std::regex (patrón), std::smatch (resultado para cadenas) y std::sregex_iterator (iterador para múltiples coincidencias).
Ejemplo 1: Verificar si una cadena coincide con un patrón
#include <iostream>#include <regex>#include <string>
int main() { std::string email = "user@example.com"; // Patrón 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 << "¡El email es válido!" << std::endl; } else { std::cout << "El email no tiene el formato correcto." << std::endl; } return 0;}La función std::regex_match verifica si toda la cadena coincide completamente con el patrón. Observa el uso de R"(...)" — es un literal de cadena sin procesar (raw string literal) que evita tener que escapar las barras invertidas.
Ejemplo 2: Búsqueda de una subcadena
#include <iostream>#include <regex>#include <string>
int main() { std::string text = "Mi número: +7 (123) 456-78-90. ¡Llámame!"; 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 << "Posición: " << match.position() << std::endl; } else { std::cout << "Número no encontrado." << std::endl; } return 0;}std::regex_search busca la primera coincidencia del patrón en la cadena. El resultado se almacena en un objeto std::smatch, del cual se puede extraer la subcadena encontrada y su posición.
2. Extracción de datos con grupos de captura (capturing groups)
Los grupos permiten extraer partes individuales de una coincidencia. Se indican con paréntesis ().
Ejemplo 3: Análisis de una fecha
#include <iostream>#include <regex>#include <string>
int main() { std::string date = "Hoy es 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 << "Fecha completa: " << match[0] << std::endl; std::cout << "Día: " << match[1] << std::endl; std::cout << "Mes: " << match[2] << std::endl; std::cout << "Año: " << match[3] << std::endl; } return 0;}Ejemplo 4: Extraer todas las coincidencias con un iterador
#include <iostream>#include <regex>#include <string>
int main() { std::string log = "ERROR: archivo no encontradoWARNING: batería bajaINFO: operación completadaERROR: tiempo de conexión agotado"; std::regex error_pattern(R"(^ERROR:\\s*(.+)$)"); // Usamos std::sregex_iterator para iterar sobre todas las líneas auto words_begin = std::sregex_iterator(log.begin(), log.end(), error_pattern); auto words_end = std::sregex_iterator(); std::cout << "Encontradas