Регулярные выражения в C++ с примерами: полное руководство для начинающих
Регулярные выражения (regex) — это мощный инструмент для поиска, проверки и замены текста по шаблону. В C++ работа с регулярными выражениями реализована через библиотеку <regex>, которая появилась в стандарте C++11. В этой статье мы разберем основы работы с regex в C++ на практических примерах, понятных даже новичкам.
Что такое регулярные выражения и зачем они нужны?
Регулярное выражение — это последовательность символов, задающая шаблон для поиска в тексте. Например, шаблон \d{3}-\d{2}-\d{2} описывает формат номера СНИЛС: три цифры, дефис, две цифры, дефис, две цифры.
Основные задачи, которые решают регулярные выражения в C++:
- Проверка корректности ввода (email, телефон, дата)
- Извлечение данных из текста
- Поиск и замена подстрок
- Разделение строк по сложным разделителям
Библиотека <regex> предоставляет три основных алгоритма:
std::regex_match— полное совпадение строки с шаблономstd::regex_search— поиск совпадения в строкеstd::regex_replace— замена совпадений по шаблону
Базовый синтаксис регулярных выражений в C++
Прежде чем писать код, разберем основные элементы синтаксиса regex, которые пригодятся в примерах:
| Символ | Значение | Пример |
|---|---|---|
. | Любой символ (кроме перевода строки) | c.t — cat, cot, cut |
\d | Цифра (0-9) | \d\d — 23, 45, 99 |
\w | Буква, цифра или знак подчеркивания | \w+ — слово |
\s | Пробельный символ | \s+ — один или более пробелов |
* | 0 или более повторений | ab*c — ac, abc, abbc |
+ | 1 или более повторений | ab+c — abc, abbc (не ac) |
? | 0 или 1 повторение | colou?r — color, colour |
{n} | Ровно n повторений | \d{3} — 123, 456 |
[abc] | Любой символ из набора | [aeiou] — гласная |
() | Группа для захвата | (\d{2})-(\d{2}) |
Пример 1: Проверка email-адреса с помощью regex_match
Начнем с простого — проверим, соответствует ли строка формату email. Используем std::regex_match, который требует полного совпадения.
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string email = "user@example.com";
// Простой шаблон для email:
// [\w.]+ — один или более символов (буквы, цифры, точка, подчеркивание)
// @ — символ собаки
// [\w.]+ — доменное имя
// \.[a-z]{2,} — точка и домен верхнего уровня (от 2 букв)
std::regex pattern(R"([\w.]+@[\w.]+\.\w{2,})");
if (std::regex_match(email, pattern)) {
std::cout << "Email корректен" << std::endl;
} else {
std::cout << "Email некорректен" << std::endl;
}
// Пример с невалидным email
email = "user@com";
if (std::regex_match(email, pattern)) {
std::cout << "Email корректен" << std::endl;
} else {
std::cout << "Email некорректен" << std::endl;
}
return 0;
}
Результат работы:
Email корректен
Email некорректен
Обратите внимание на сырую строку R"(...)" — она позволяет не экранировать обратные слеши, что делает шаблон более читаемым.
Пример 2: Поиск всех номеров телефонов в тексте (regex_search)
Теперь найдем все номера телефонов в формате +7 (XXX) XXX-XX-XX внутри большого текста. Используем std::regex_search в цикле с итератором.
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string text = "Контакты: +7 (495) 123-45-67 и +7 (916) 987-65-43. "
"Дополнительно: 8-800-555-35-35";
// Шаблон для российского номера: +7 (код) XXX-XX-XX
std::regex phone_pattern(R"(\+7\s\(\d{3}\)\s\d{3}-\d{2}-\d{2})");
// Итератор для поиска всех совпадений
auto words_begin = std::sregex_iterator(text.begin(), text.end(), phone_pattern);
auto words_end = std::sregex_iterator();
std::cout << "Найденные номера:" << std::endl;
int count = 1;
for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
std::smatch match = *i;
std::cout << count++ << ". " << match.str() << std::endl;
}
if (words_begin == words_end) {
std::cout << "Номера не найдены