无法让regex_search找到所有匹配项

时间:2016-05-16 15:39:27

标签: regex c++11

这不是thisthis问题的重复,因为我使用的是最新的g ++ 6.1。

以下是我正在尝试的一个简单示例:

int main() {
   std::string data = "a,b,c,d,e,f,g";
   std::smatch m;
   regex_search(data, m, std::regex("(\\w)"));
   std::cout << m.size() << std::endl;
   for (auto i = 0U; i != m.size(); i++)
       std::cout << m.position(i) << " " << m[i].str() << std::endl;
   return 0;
}

此示例输出2作为匹配数,而我预期为7,因为data中的每个字母都应与\w匹配。我该如何解决这个问题?

此外,两个匹配都指向字符串开头的a

2 个答案:

答案 0 :(得分:1)

regex_seach不提供扫描整个字符串的任何工具,它只是在第一次匹配时停止。幸运的是<regex>图书馆提供了std::regex_iterator来完成工作:

int main() {
   std::string data = "a,b,c,d,e,f,g";
   std::regex exp =  std::regex("(\\w)");

   auto mbegin = std::sregex_iterator(data.begin(), data.end(), exp);
   auto mend = std::sregex_iterator();

   for (auto it = mbegin; it != mend; ++it)
     cout << it->str() << endl;

   return 0;
}

唯一需要注意的是,所使用的std::regex的生命周期必须匹配(至少)迭代器中的一个,因为std::regex_iterator在内部存储了一个指向它的指针。

答案 1 :(得分:1)

这是excerpt from Finding All Regex Matches at regular-expressions.info

  

通过使用三个参数调用构造函数构造一个对象:字符串迭代器指示搜索的起始位置字符串迭代器指示搜索的结束位置,和正则表达式对象。如果找到任何匹配项,则对象将在构造时保持第一个匹配项。使用默认构造函数构造另一个迭代器对象以获取序列结束迭代器。您可以将第一个对象与第二个对象进行比较,以确定是否还有其他匹配项。只要第一个对象不等于第二个对象,就可以取消引用第一个对象以获取match_results对象

因此,您可以使用以下内容来获取匹配项及其位置:

#include <iostream>
#include <string>
#include <regex>
using namespace std;

int main() {
    std::regex r(R"(\w)");
    std::string s("a,b,c,d,e,f,g");
    for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), r);
                             i != std::sregex_iterator();
                             ++i)
    {
        std::smatch m = *i;
        std::cout << "Match value: " << m.str() << " at Position " << m.position() << '\n';
    }
    return 0;
}

请参阅IDEONE demo

结果:

Match value: a at Position 0
Match value: b at Position 2
Match value: c at Position 4
Match value: d at Position 6
Match value: e at Position 8
Match value: f at Position 10
Match value: g at Position 12

使用原始字符串文字更好地声明正则表达式(R"(\w)"\w正则表达式模式)。