Регулярные выражения в C++ с примерами: от основ до практики
Регулярные выражения (regex) — мощный инструмент для поиска, извлечения и замены фрагментов текста по шаблону. В C++ поддержка регулярных выражений появилась в стандарте C++11 и реализована в библиотеке <regex>. В этой статье мы разберем практические примеры использования std::regex, которые помогут вам эффективно обрабатывать строки в ваших проектах.
1. Основы std::regex: создание и простой поиск
Для работы с регулярными выражениями в C++ используются три основных класса: std::regex (шаблон), std::smatch (результат для строки) и std::sregex_iterator (итератор для множественных совпадений).
Пример 1: Проверка соответствия строки шаблону
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string email = "user@example.com";
// Шаблон для проверки email (упрощенный)
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 корректен!" << std::endl;
} else {
std::cout << "Email не соответствует формату." << std::endl;
}
return 0;
}
Функция std::regex_match проверяет, соответствует ли вся строка шаблону полностью. Обратите внимание на использование R"(...)" — это raw string literal, который позволяет не экранировать обратные слеши.
Пример 2: Поиск подстроки
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string text = "Мой номер: +7 (123) 456-78-90. Позвоните мне!";
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 << "Найден номер: " << match.str() << std::endl;
std::cout << "Позиция: " << match.position() << std::endl;
} else {
std::cout << "Номер не найден." << std::endl;
}
return 0;
}
std::regex_search ищет первое совпадение с шаблоном в строке. Результат сохраняется в объект std::smatch, из которого можно извлечь найденную подстроку и её позицию.
2. Извлечение данных с помощью групп (capturing groups)
Группы позволяют извлекать отдельные части совпадения. Они обозначаются круглыми скобками ().
Пример 3: Парсинг даты
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string date = "Сегодня 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 << "Полная дата: " << match[0] << std::endl;
std::cout << "День: " << match[1] << std::endl;
std::cout << "Месяц: " << match[2] << std::endl;
std::cout << "Год: " << match[3] << std::endl;
}
return 0;
}
Пример 4: Извлечение всех совпадений с помощью итератора
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string log = "ERROR: файл не найден\nWARNING: низкий заряд батареи\nINFO: операция завершена\nERROR: таймаут соединения";
std::regex error_pattern(R"(^ERROR:\s*(.+)$)");
// Используем std::sregex_iterator для перебора всех строк
auto words_begin = std::sregex_iterator(log.begin(), log.end(), error_pattern);
auto words_end = std::sregex_iterator();
std::cout << "Найденные ошибки:" << std::endl;
for (auto it = words_begin; it != words_end; ++it) {
std::cout << "- " << (*it)[1] << std::endl;
}
return 0;
}
В этом примере итератор std::sregex_iterator находит все строки, начинающиеся с ERROR:, и извлекает текст ошибки из первой группы.
3. Замена текста с помощью std::regex_replace
Функция std::regex_replace позволяет заменять найденные по шаблону фрагменты на новый текст. Можно использовать ссылки на группы ($1, $2 и т.д.) в строке замены.
Пример 5: Форматирование номера телефона
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string text = "Контакты: 8(123)4567890 и +7(987)6543210";
std::regex phone_pattern(R"((\+?7|8)\((\d{3})\)(\d{7}))");
// Заменяем на формат: +7 (XXX) XXX-XX-XX
std::string formatted = std::regex_replace(text, phone_pattern, "+7 ($2) $3");
std::cout << "Исходный текст: " << text << std::endl;
std::cout << "После замены: " << formatted << std::endl;
return 0;
}
Пример 6: Маскирование конфиденциальных данных
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string data = "Email: john.doe@company.com, телефон: +7-999-123-45-67";
std::regex email_pattern(R"((\w)[\w.-]*@[\w