2010-06-28 53 views
5

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

正则表达式的尝试:

(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次。任何帮助都感激不尽。

+0

如果你能告诉我们更多关于输入格式以及你想如何解析的信息,这将有很大帮助。 – 2010-06-28 15:51:22

+0

输入是字符串流,在这个例子中我希望得到3个组(BEN KL),(LHR BA)和(MAN QFL)。我知道在这种情况下,即使不使用正则表达式,我们也可以做到这一点,但我只是想看看是否可以保持与使用正则表达式的现有代码一致。 – omshanti 2010-06-29 10:25:47

回答

0

这就是预期的行为:当一个捕获组由一个量词控制时,每个重复将覆盖前一次捕获的内容。获得所有比赛的最简单的方法是把一个捕获组围绕整个事情,就像这样:

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

该小组最终将包含BENKL/LHRBA/MANQFL,您可以在/分裂。

1

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

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

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