Поиск всех совпадений с шаблоном

При использовании функции regex_search() мы получим только первое совпадение с шаблоном регулярного выражения:

std::regex rgx("[0-9]+");
std::string str("10 20 30");
std::smatch m;
if (std::regex_search(str, m, rgx)) {
   std::cout << m.str() << std::endl;         // 10
}

Чтобы получить все числа из строки можно использовать цикл while и внутри цикла присваивать переменной str фрагмент, возвращаемый методом suffix():

std::regex rgx("[0-9]+");
std::string str("s10 t20 n30k");
std::smatch m;
while (std::regex_search(str, m, rgx)) {
   std::cout << m.str() << '+';
   str = m.suffix().str();
} // 10+20+30+
std::cout << std::endl;

В данном примере на каждой итерации цикла создается новая строка и при этом изменяется исходная строка. Чтобы сделать процесс поиска всех совпадений более эффективным следует воспользоваться классом regex_iterator:

template<typename _Bi_iter,
   typename _Ch_type = typename iterator_traits<_Bi_iter>::value_type,
   typename _Rx_traits = regex_traits<_Ch_type> >
      class regex_iterator

Псевдонимы:

typedef regex_iterator<const char*> cregex_iterator;
typedef regex_iterator<const wchar_t*> wcregex_iterator;
typedef regex_iterator<string::const_iterator> sregex_iterator;
typedef regex_iterator<wstring::const_iterator> wsregex_iterator;

Основные конструкторы класса regex_iterator:

regex_iterator();
regex_iterator(_Bi_iter first, _Bi_iter last,
               const regex_type &re,
               match_flag_type flags=match_default);

Первый конструктор создает объект, указывающий на конец последовательности. Параметры второго конструктора совпадают с одноименными параметрами функции regex_search(). При разыменовании итератора с помощью оператора * или -> доступен объект класса match_results. При увеличении на единицу с помощью оператора ++ выполняется поиск следующего фрагмента, совпадающего с шаблоном регулярного выражения. Если ничего не найдено, то возвращается объект, созданный с помощью первого конструктора. Для сравнения двух объектов класса regex_iterator можно использовать операторы == и !=.

Получим все числа из строки с помощью класса sregex_iterator (листинг 10.2).

Листинг 10.2. Поиск всех совпадений с шаблоном

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

int main() {
   std::regex rgx("[0-9]+");
   std::string str("s10 t20 n30k");
   std::sregex_iterator istart(str.begin(), str.end(), rgx);
   std::sregex_iterator iend;
   while (istart != iend) {
      std::cout << istart->str() << '+';
      // std::cout << (*istart).str() << '+';
      ++istart;
   } // 10+20+30+
   std::cout << std::endl;
   return 0;
}
Примечание

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

Помощь сайту

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

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