如何使用std :: regex匹配多个结果

时间:2014-02-10 00:45:56

标签: c++ regex

例如。如果我有一个像“第一个第二个第三个”的字符串,我想在一个操作中匹配每个单词,逐个输出。

我只是认为“(\ b \ S * \ b){0,}”会起作用。但事实上它没有。

我该怎么办?

这是我的代码:

#include<iostream>
#include<string>
using namespace std;
int main()
{
    regex exp("(\\b\\S*\\b)");
    smatch res;
    string str = "first second third forth";
    regex_search(str, res, exp);
    cout << res[0] <<" "<<res[1]<<" "<<res[2]<<" "<<res[3]<< endl;
}   

我期待着您的帮助。 :)

6 个答案:

答案 0 :(得分:23)

只需在regex_searching上迭代你的字符串,就像这样:

{
    regex exp("(\\b\\S*\\b)");
    smatch res;
    string str = "first second third forth";

    string::const_iterator searchStart( str.cbegin() );
    while ( regex_search( searchStart, str.cend(), res, exp ) )
    {
        cout << ( searchStart == str.cbegin() ? "" : " " ) << res[0];  
        searchStart = res.suffix().first;
    }
    cout << endl;
}

答案 1 :(得分:16)

这可以在regex的{​​{1}}中完成。

两种方法:

  1. 您可以使用C++11中的()来定义您的抓拍。

    像这样:

    regex

    现场直播:http://coliru.stacked-crooked.com/a/e1447c4cff9ea3e7

  2. 您可以使用string var = "first second third forth"; const regex r("(.*) (.*) (.*) (.*)"); smatch sm; if (regex_search(var, sm, r)) { for (int i=1; i<sm.size(); i++) { cout << sm[i] << endl; } }

    sregex_token_iterator()

    现场直播:http://coliru.stacked-crooked.com/a/677aa6f0bb0612f0

答案 2 :(得分:10)

您可以使用suffix()函数,并再次搜索,直到找不到匹配项:

int main()
{
    regex exp("(\\b\\S*\\b)");
    smatch res;
    string str = "first second third forth";

    while (regex_search(str, res, exp)) {
        cout << res[0] << endl;
        str = res.suffix();
    }
}   

答案 3 :(得分:6)

随意使用我的代码。它将捕获所有比赛中的所有组:

vector<vector<string>> U::String::findEx(const string& s, const string& reg_ex, bool case_sensitive)
{
    regex rx(reg_ex, case_sensitive ? regex_constants::icase : 0);
    vector<vector<string>> captured_groups;
    vector<string> captured_subgroups;
    const std::sregex_token_iterator end_i;
    for (std::sregex_token_iterator i(s.cbegin(), s.cend(), rx);
        i != end_i;
        ++i)
    {
        captured_subgroups.clear();
        string group = *i;
        smatch res;
        if(regex_search(group, res, rx))
        {
            for(unsigned i=0; i<res.size() ; i++)
                captured_subgroups.push_back(res[i]);

            if(captured_subgroups.size() > 0)
                captured_groups.push_back(captured_subgroups);
        }

    }
    captured_groups.push_back(captured_subgroups);
    return captured_groups;
}

答案 4 :(得分:4)

我对the documentation的解读是,regex_search搜索了第一场比赛,而std::regex中没有任何一项功能执行&#34;扫描&#34;正如你所寻找的。但是,Boost库似乎支持这一点,如C++ tokenize a string using a regular expression

中所述

答案 5 :(得分:1)

sregex_token_iterator似乎是理想的,有效的解决方案,但所选答案中给出的示例还有很多不足之处。相反,我在这里找到了一些很好的例子: http://www.cplusplus.com/reference/regex/regex_token_iterator/regex_token_iterator/

为方便起见,我复制并粘贴了该页面显示的示例代码。我声称代码没有任何功劳。

// regex_token_iterator example
#include <iostream>
#include <string>
#include <regex>

int main ()
{
  std::string s ("this subject has a submarine as a subsequence");
  std::regex e ("\\b(sub)([^ ]*)");   // matches words beginning by "sub"

  // default constructor = end-of-sequence:
  std::regex_token_iterator<std::string::iterator> rend;

  std::cout << "entire matches:"; 
  std::regex_token_iterator<std::string::iterator> a ( s.begin(), s.end(), e );
  while (a!=rend) std::cout << " [" << *a++ << "]";
  std::cout << std::endl;

  std::cout << "2nd submatches:";
  std::regex_token_iterator<std::string::iterator> b ( s.begin(), s.end(), e, 2 );
  while (b!=rend) std::cout << " [" << *b++ << "]";
  std::cout << std::endl;

  std::cout << "1st and 2nd submatches:";
  int submatches[] = { 1, 2 };
  std::regex_token_iterator<std::string::iterator> c ( s.begin(), s.end(), e, submatches );
  while (c!=rend) std::cout << " [" << *c++ << "]";
  std::cout << std::endl;

  std::cout << "matches as splitters:";
  std::regex_token_iterator<std::string::iterator> d ( s.begin(), s.end(), e, -1 );
  while (d!=rend) std::cout << " [" << *d++ << "]";
  std::cout << std::endl;

  return 0;
}

Output:
entire matches: [subject] [submarine] [subsequence]
2nd submatches: [ject] [marine] [sequence]
1st and 2nd submatches: [sub] [ject] [sub] [marine] [sub] [sequence]
matches as splitters: [this ] [ has a ] [ as a ]