std :: regex эквивалент глобального модификатора '/ g' - PullRequest
6 голосов
/ 26 мая 2011

В Perl я могу сделать это:

$text = '1747239';
@matches = ($text =~ m/(\d)/g);
# @matches now contains ('1', '7', '4', '7', '2', '3', '9')

Используя сопоставление регулярных выражений в C ++, как лучше всего воспроизвести это поведение, получить набор совпадений, включая все совпадения?

У меня есть это на данный момент: -

compiledRegex = std::regex(regex, std::tr1::regex_constants::extended);
regex_search(text, results, compiledRegex);

int count = results.size();
// Alloc pointer array based on count * sizeof(mystruct).
for ( std::cmatch::iterator match = results.begin(); 
      match != results.end(); 
      ++match )
{
    // Do something with match;
}

Однако это даст мне только первое совпадение, точно так же, как в Perl без / g, но я бы хотел эффект / g.

Итак, есть ли хороший способ сделать это, или я должен продолжать выполнять регулярные выражения снова и снова?

1 Ответ

9 голосов
/ 26 мая 2011

Вам следует позвонить regex_search несколько раз.Его возвращаемое значение указывает, есть ли еще совпадения.Каждый раз, когда вы звоните, вы получаете новый матч.Итератор, возвращаемый по результатам, проходит по групповым подсовпадениям, определенным в вашем регулярном выражении.Первая запись - это всегда полное совпадение, поэтому в вашем случае count == 1

std::string::const_iterator text_iter = text.cbegin();
compiledRegex = std::regex(regex, std::tr1::regex_constants::extended);

while (regex_search(text_iter, text.end(), results, compiledRegex))
{
    int count = results.size();
    // Alloc pointer array based on count * sizeof(mystruct).
    for ( std::cmatch::iterator group = results.begin();
          group != results.end();
          ++group )
    {
        // If you uses grouping in your search here you can access each group
    }

   std::cout << std::string(results[0].first, results[0].second) << endl;
   text_iter = results[0].second;
}

Надеюсь, это поможет

...