Expressions régulières en C++ avec exemples : des bases à la pratique
Les expressions régulières (regex) sont un outil puissant pour rechercher, extraire et remplacer des fragments de texte selon un motif. En C++, le support des expressions régulières est apparu avec la norme C++11 et est implémenté dans la bibliothèque <regex>. Dans cet article, nous analyserons des exemples pratiques d'utilisation de std::regex qui vous aideront à traiter efficacement les chaînes de caractères dans vos projets.
1. Bases de std::regex : création et recherche simple
Pour travailler avec les expressions régulières en C++, trois classes principales sont utilisées : std::regex (motif), std::smatch (résultat pour une chaîne) et std::sregex_iterator (itérateur pour les correspondances multiples).
Exemple 1 : Vérification de la conformité d'une chaîne à un motif
#include <iostream>#include <regex>#include <string>
int main() { std::string email = "user@example.com"; // Motif pour vérifier un email (simplifié) 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 valide !" << std::endl; } else { std::cout << "Email non conforme au format." << std::endl; } return 0;}La fonction std::regex_match vérifie si la chaîne entière correspond complètement au motif. Notez l'utilisation de R"(...)" — il s'agit d'un littéral de chaîne brute qui permet de ne pas échapper les antislashs.
Exemple 2 : Recherche d'une sous-chaîne
#include <iostream>#include <regex>#include <string>
int main() { std::string text = "Mon numéro : +7 (123) 456-78-90. Appelez-moi !"; 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 << "Numéro trouvé : " << match.str() << std::endl; std::cout << "Position : " << match.position() << std::endl; } else { std::cout << "Numéro non trouvé." << std::endl; } return 0;}std::regex_search recherche la première correspondance avec le motif dans la chaîne. Le résultat est stocké dans un objet std::smatch, à partir duquel on peut extraire la sous-chaîne trouvée et sa position.
2. Extraction de données à l'aide de groupes (capturing groups)
Les groupes permettent d'extraire des parties individuelles d'une correspondance. Ils sont indiqués par des parenthèses ().
Exemple 3 : Analyse d'une date
#include <iostream>#include <regex>#include <string>
int main() { std::string date = "Aujourd'hui 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 << "Date complète : " << match[0] << std::endl; std::cout << "Jour : " << match[1] << std::endl; std::cout << "Mois : " << match[2] << std::endl; std::cout << "Année : " << match[3] << std::endl; } return 0;}Exemple 4 : Extraction de toutes les correspondances avec un itérateur
#include <iostream>#include <regex>#include <string>
int main() { std::string log = "ERROR : fichier non trouvéWARNING : batterie faibleINFO : opération terminéeERROR : timeout de connexion"; std::regex error_pattern(R"(^ERROR :\\s*(.+)$)"); // Utilisation de std::sregex_iterator pour parcourir toutes les lignes auto words_begin = std::sregex_iterator(log.begin(), log.end(), error_pattern); auto words_end = std::sregex_iterator(); std::cout << "Trouvé