2014-12-11 5 views
2

Я пытаюсь найти несколько цифр в строке. Я в состоянии получить только последний, или предварительно заданное количество цифр:Как получить неизвестное количество совпадений регулярных выражений?

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

int main() 
{ 
    std::string s("aaabbbccd123456eeffgg"); 
    std::smatch match; 
    std::regex braced_regex("(\\w+)(\\d{2,})(\\w+)"); 
    std::regex plus_regex("(\\w+)(\\d+)(\\w+)"); 

    auto printer = [](auto& match) { 
      std::ssub_match sub(match); 
      std::string match_substring(sub.str()); 
      std::cout << match_substring << '\n'; 
    }; 

    std::regex_match(s, match, braced_regex); 
    std::cout << "Number of braced matches: " << match.size() << '\n'; 
    std::for_each(match.begin(), match.end(), printer); 

    std::regex_match(s, match, plus_regex); 
    std::cout << "Number of plus matches: " << match.size() << '\n'; 
    std::for_each(match.begin(), match.end(), printer); 
    return 0; 
} 

Результат:

Number of braced matches: 4 
aaabbbccd123456eeffgg 
aaabbbccd1234 
56 
eeffgg 
Number of plus matches: 4 
aaabbbccd123456eeffgg 
aaabbbccd12345 
6 
eeffgg 

Как я могу получить всю числовую последовательность, то есть 123456 из предоставленной строки ?

+0

Обратите внимание, что регулярное выражение * строку * является хорошим местом для использования строки (C++ 11): 'R" (([A-Za-Z] +) (\ d {2,}) ([a-zA-Z] +)) "' – Jarod42

+0

Только для стиля: [очищенный код] (http: //coliru.stacked-crooked.com/a/cd87f7ea341a5f18) –

+0

@ Jarod42 Спасибо за подсказку. –

ответ

2
([a-zA-Z]+)(\\d{2,})([a-zA-Z]+) 

Вы можете попробовать это. \w === [a-zA-Z0-9_] .so \w+ будет соответствовать макс это can.So он позволяет \d{2,} иметь только 2.

или

(\\w+?)(\\d{2,})(\\w+) 

Сделайте первый \w не жадный. См. live demo.

+0

@SebastianKramer, если вы хотите его использовать, тогда сделайте он 'lazy', открывая« +? »после него – vks

+0

Почему я должен делать [: alpha:] lazy? Разве это не будет соответствовать префиксу цифры? –

+0

@SebastianKramer alpha такой же, как '\ w'. Так что он снова будет поглощать ваши цифры, и вы не получите его все, если не сделаете его ленивым – vks

2

Я думаю, что проблема в том, что цифры считаются частями слова и совпадают с \w. Я был бы соблазн использовать \D значение не цифра:

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

int main() 
{ 
    std::string s("aaabbbccd123456eeffgg"); 
    std::smatch match; 
    std::regex plus_regex("(\\D+)(\\d+)(\\D+)"); 

    auto printer = [](auto& match) { 
      std::ssub_match sub(match); 
      std::string match_substring(sub.str()); 
      std::cout << match_substring << '\n'; 
    }; 

    std::regex_match(s, match, plus_regex); 
    std::cout << "Number of plus matches: " << match.size() << '\n'; 
    std::for_each(match.begin(), match.end(), printer); 
    return 0; 
} 

Выход:

Number of plus matches: 4 
aaabbbccd123456eeffgg 
aaabbbccd 
123456 
eeffgg 

Другая возможность (в зависимости от того, что вы хотите), чтобы использовать std::regex_search(), который не пытается соответствовать целую строку, но позволяет сопоставлять элементы посередине:

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

int main() 
{ 
    std::string s("aaabbbccd123456eeffgg"); 
    std::smatch match; 
    std::regex braced_regex("\\d{2,}"); // just the numbers 

    auto printer = [](auto& match) { 
      std::ssub_match sub(match); 
      std::string match_substring(sub.str()); 
      std::cout << match_substring << '\n'; 
    }; 

    std::regex_search(s, match, braced_regex); // NOTE: regex_search()! 
    std::cout << "Number of braced matches: " << match.size() << '\n'; 
    std::for_each(match.begin(), match.end(), printer); 
} 

Выход:

Number of braced matches: 1 
123456 
1

В:

(\\w+)(\\d{2,})(\\w+) 

\\w+ соответствует любому символу [A-Za-z0-9_], поэтому он соответствует также 1234

, чтобы соответствовать всему изменению номера \\w на [A-Za-Z_ ], так что вы будете иметь:

std::regex braced_regex("([a-zA-Z_]+)(\\d{2,})(\\w+)"); 
Смежные вопросы