【问题标题】:How do I capture all matches of a repeating group with Boost::regex_search?如何使用 Boost::regex_search 捕获重复组的所有匹配项?
【发布时间】:2011-03-09 04:48:24
【问题描述】:

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

正则表达式尝试:

(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++代码sn-p:

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 次。任何帮助将不胜感激。

【问题讨论】:

  • 如果您能告诉我们更多有关输入格式以及您希望如何解析它的信息,将会很有帮助。
  • 输入是字符串流,在这个例子中,我希望得到 3 个组(BEN KL)、(LHR BA)和(MAN QFL)。我知道在这种情况下,即使不使用正则表达式我们也可以做到这一点,但我只是想看看我是否可以使其与使用正则表达式的现有代码保持一致。

标签: c++ regex boost-regex


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-16
          • 2021-06-21
          • 1970-01-01
          • 2022-01-11
          • 1970-01-01
          • 2016-10-28
          相关资源
          最近更新 更多