Expresiones regulares en C++: una poderosa herramienta para trabajar con texto
Las expresiones regulares (regex) son una herramienta extremadamente poderosa para buscar, extraer y reemplazar fragmentos de texto según un patrón determinado. En C++, el soporte para expresiones regulares apareció en el estándar C++11 y se implementa en el archivo de encabezado <regex>. En este artículo, analizaremos en detalle cómo usar expresiones regulares en C++ con ejemplos prácticos.
Componentes principales de la biblioteca <regex>
La biblioteca <regex> incluye varias clases y funciones clave:
std::regex— clase que representa una expresión regular compilada.std::smatch— contenedor para almacenar resultados de búsqueda (para cadenas de tipostd::string).std::regex_match— verifica si toda la cadena coincide con el patrón.std::regex_search— busca la primera coincidencia del patrón en la cadena.std::regex_replace— reemplaza las coincidencias con el texto especificado.
Veamos cada uno de estos componentes con ejemplos.
Ejemplo 1: Verificar si una cadena coincide con un patrón (regex_match)
La función std::regex_match devuelve true si toda la cadena coincide completamente con la expresión regular. Esto es ideal para la validación de datos, por ejemplo, verificar un email o un número de teléfono.
#include <iostream>#include <regex>#include <string>
int main() { std::string email = "user@example.com"; // Patrón para verificar 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 es válido." << std::endl; } else { std::cout << "Email no es válido." << std::endl; } // Ejemplo con email no válido std::string bad_email = "user@.com"; if (std::regex_match(bad_email, pattern)) { std::cout << "Email es válido." << std::endl; } else { std::cout << "Email no es válido." << std::endl; } return 0;}En este ejemplo, usamos una cadena raw R"(...)" para evitar escapar las barras invertidas. El patrón verifica que la cadena contenga una parte local, el signo @, un nombre de dominio y un dominio de nivel superior.
Ejemplo 2: Buscar una subcadena en el texto (regex_search)
Si necesita encontrar la primera coincidencia de un patrón dentro de una cadena, se usa std::regex_search. Los resultados se almacenan en un objeto std::smatch.
#include <iostream>#include <regex>#include <string>
int main() { std::string text = "Mi número de teléfono: +7 (123) 456-78-90. ¡Llámame!"; // Patrón para buscar un número de teléfono ruso 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;}El objeto match contiene no solo la cadena encontrada, sino también información sobre la posición de la coincidencia. El método match.str() devuelve el fragmento encontrado, y match.position() devuelve el índice de inicio de la coincidencia en la cadena original.
Ejemplo 3: Reemplazar texto con regex_replace
La función std::regex_replace reemplaza todas las ocurrencias del patrón con la cadena especificada. Se pueden usar referencias inversas (backrefer