Синтаксис регулярных выражений

Обычные символы, не имеющие специального значения, могут присутствовать в строке шаблона, и они будут трактоваться как есть. Пример указания в шаблоне последовательности обычных символов:

std::regex rgx("строка");
std::cout << std::regex_match("строка", rgx) << std::endl; // 1

Экранирование специальных символов

Внутри регулярного выражения символы ., ^, $, *, +, ?, {, [, ], \, |, ( и ) имеют специальное значение. Если эти символы должны трактоваться как есть, то их следует экранировать с помощью слэша. Некоторые специальные символы теряют свое специальное значение, если их разместить внутри квадратных скобок. В этом случае экранировать их не нужно. Например, метасимвол «точка» соответствует любому символу, кроме символа перевода строки. Если необходимо найти именно точку, то перед точкой необходимо указать символ \ или поместить точку внутри квадратных скобок ([.]). Продемонстрируем это на примере проверки правильности введенной даты (листинг 10.1).

Листинг 10.1. Проверка правильности ввода даты

#include <iostream>
#include <locale>
#include <string>
#include <regex>

int main() {
   std::setlocale(LC_ALL, "Russian_Russia.1251");
   std::string d("29,07.2019"); // Вместо точки указана запятая
   // Символ "\" не указан перед точкой
   std::regex rgx("[0-3][0-9].[01][0-9].[12][09][0-9][0-9]");
   if (std::regex_match(d, rgx))
      std::cout << "Дата введена правильно" << std::endl;
   else
      std::cout << "Дата введена неправильно" << std::endl;
   // Т. к. точка означает любой символ, выведет:
   // Дата введена правильно

   // Символ "\" указан перед точкой
   rgx = "[0-3][0-9]\\.[01][0-9]\\.[12][09][0-9][0-9]";
   if (std::regex_match(d, rgx))
      std::cout << "Дата введена правильно" << std::endl;
   else
      std::cout << "Дата введена неправильно" << std::endl;
   // Т. к. перед точкой указан символ "\", выведет:
   // Дата введена неправильно

   // Точка внутри квадратных скобок
   rgx = "[0-3][0-9][.][01][0-9][.][12][09][0-9][0-9]";
   if (std::regex_match(d, rgx))
      std::cout << "Дата введена правильно" << std::endl;
   else
      std::cout << "Дата введена неправильно" << std::endl;
   // Выведет: Дата введена неправильно
   return 0;
}

Следует учитывать, что символ обратного слеша является специальным не только в шаблоне регулярного выражения, но и в строке. Поэтому его нужно экранировать. Например, проверим равна ли строка значению "\s". Внутри шаблона регулярного выражения данная комбинация символов является специальной и обозначает любые пробельные символы. Поэтому внутри шаблона мы должны добавить еще три слеша, чтобы экранировать специальную комбинацию:

std::regex rgx("^\\\\s$");
std::cout << std::regex_search("\\s", rgx) << std::endl; // 1

Посмотрите сколько слешей! Чтобы не путаться, следует выводить строку с шаблоном в консоль и смотреть, что получилось в итоге. Помните, что экранирование внутри шаблона должно быть видно при выводе:

std::cout << "^\\\\s$" << std::endl;  // ^\\s$
std::cout << "\\s" << std::endl;      // \s

Можно также использовать raw-строки (см. разд. 7.5 и 8.6):

std::cout << R"(^\\s$)" << std::endl;         // ^\\s$
std::cout << R"...(^\\s$)..." << std::endl;   // ^\\s$
std::wcout << LR"(^\\s$)" << std::endl;       // ^\\s$

Учебник C++ (MinGW-W64)
Учебник C++ (MinGW-W64) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов