如何使用Boost :: regex_search捕获重复组的所有匹配项?

时间:2010-06-28 15:18:09

标签: c++ regex boost-regex

我正在尝试使用正则表达式解析输入字符串。在尝试捕获重复组时遇到问题。我似乎总是匹配该组的最后一个实例。我尝试过使用Reluctant(非贪婪)量词,但我似乎错过了一些东西。有人可以帮忙吗?

尝试使用正则表达式:

(OS)\\s((\\w{3})(([A-Za-z0-9]{2})|(\\w{3})(\\w{3}))\\/{0,1}){1,5}?\\r

(OS)\\s((\\w{3}?)(([A-Za-z0-9]{2}?)|(\\w{3}?)(\\w{3}?))\\/{0,1}?){1,5}?\\r

输入字符串:

OS BENKL/LHRBA/MANQFL\r\n

我似乎总是得到最后一组是MANQFL组(MAN QFL),我的目标是获得所有三组(可以有1-5组):

(BEN KL) , (LHR BA) and (MAN QFL). 

C ++代码段:

std::string::const_iterator start = str.begin(), end = str.end(); 
while(regex_search(start,end,what,expr)) 
{ 
  cout << what[0]; 
  cout << what[1]; 
  ... 
  start += what.position () + what.length (); 
}

这个循环只有一次,而我希望它在这个例子中运行3次。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:4)

从boost :: regex中获取多个匹配项的最佳方法是使用regex_iterators。这个例子可以做你想要的。

#include <iostream>
#include <string>
#include <boost/regex.hpp>

int main() {
    std::string a = "OS BENKL/LHRBA/MANQFL\r\n";
    const boost::regex re("[A-Z]{3}[A-Z]*");
    boost::sregex_iterator res(a.begin(),a.end(),re);
    boost::sregex_iterator end;
    for (; res != end; ++res)
        std::cout << (*res)[0] << std::endl;
}

答案 1 :(得分:1)

我所知道的唯一正则表达式可以为您提供捕获组的所有迭代,这是.NET正则表达式的风格。通常,正则表达式引擎只保存每个捕获组的最后一次迭代。

此类问题的一般解决方案是使用一个正则表达式捕获组的所有迭代,并使用第二个正则表达式将第一个正则表达式的结果拆分为单独的项。艾伦已经解释过如何在这种特殊情况下做到这一点。

答案 2 :(得分:0)

这是预期的行为:当捕获组由量词控制时,每次重复都会覆盖前一次捕获的内容。获得所有匹配的最简单方法是将捕获组放在整个事物上,如下所示:

(OS)\\s(((\\w{3})(([A-Za-z0-9]{2})|(\\w{3})(\\w{3}))\\/?){1,5})\\r

该群组最终会包含BENKL/LHRBA/MANQFL,您可以在/上拆分。

答案 3 :(得分:0)

请阅读有关重复捕获的部分:http://www.boost.org/doc/libs/1_47_0/libs/regex/doc/html/boost_regex/captures.html

基本上,您想要的是一个实验性功能,可以通过将适当的#defines和标志传递给您的regex_search调用来启用。