5

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

正则表达式尝试:

(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

4 回答 4

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;
}
于 2011-06-14T23:09:21.040 回答
1

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

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

于 2010-07-12T08:05:54.357 回答
0

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

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

该组最终将包含BENKL/LHRBA/MANQFL,您可以在/.

于 2010-06-28T17:55:26.973 回答
0

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

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

于 2011-08-05T17:58:42.980 回答