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

9udxz4iz  于 2022-11-18  发布在  其他
关注(0)|答案(6)|浏览(203)

例如,如果我有一个字符串“first second third forth”,我想在一个操作中匹配每个单词,然后逐个输出。
我只是以为"(\\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;
}
q8l4jmvw

q8l4jmvw1#

只需在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;
}
f0ofjuux

f0ofjuux2#

这可以在C++11regex中完成。

两种方法:
1.您可以在regex中使用()来定义捕获(子表达式)。
就像这样:

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;
        }
    }

现场观看:http://coliru.stacked-crooked.com/a/e1447c4cff9ea3e7
1.您可以使用sregex_token_iterator()

string var = "first second third forth";

 regex wsaq_re("\\s+"); 
 copy( sregex_token_iterator(var.begin(), var.end(), wsaq_re, -1),
     sregex_token_iterator(),
     ostream_iterator<string>(cout, "\n"));

现场观看:http://coliru.stacked-crooked.com/a/677aa6f0bb0612f0

irlmq6kh

irlmq6kh3#

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 ]
rslzwgfq

rslzwgfq4#

您可以使用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();
    }
}
khbbv19g

khbbv19g5#

我的代码将捕获所有匹配中的所有组:

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;
}
hivapdat

hivapdat6#

我对the documentation的阅读是,regex_search搜索第一个匹配项,并且std::regex中的任何函数都不执行您要查找的“扫描”。

相关问题