【问题标题】:Getting sub-match_results with boost::regex使用 boost::regex 获取 sub-match_results
【发布时间】:2011-08-12 12:03:34
【问题描述】:

嘿,假设我有这个正则表达式:(test[0-9])+

我匹配它:test1test2test3test0

const bool ret = boost::regex_search(input, what, r);

for (size_t i = 0; i < what.size(); ++i)
    cout << i << ':' << string(what[i]) << "\n";

现在,what[1] 将是 test0(最后一次出现)。假设我需要得到test1, 2 和 3:我该怎么办?

注意:真正的正则表达式极其复杂,并且必须保持一个整体匹配,因此将示例正则表达式更改为 (test[0-9]) 将不起作用。

【问题讨论】:

    标签: c++ regex boost boost-regex


    【解决方案1】:

    我认为 Dot Net 有能力制作单个捕获组集合,以便 (grp)+ 将在 group1 上创建一个集合对象。 boost 引擎的 regex_search() 就像任何普通的匹配函数一样。你坐在一个 while() 循环中,匹配最后一个匹配停止的模式。您使用的表单没有使用出价迭代器,因此该函数不会从上一个匹配停止的地方开始下一个匹配。

    您可以使用迭代器形式:
    编辑 - 您也可以使用标记迭代器,定义要迭代的组。在下面的代码中添加)。

    #include <boost/regex.hpp> 
    #include <string> 
    #include <iostream> 
    
    using namespace std;
    using namespace boost;
    
    int main() 
    { 
        string input = "test1 ,, test2,, test3,, test0,,";
        boost::regex r("(test[0-9])(?:$|[ ,]+)");
        boost::smatch what;
    
        std::string::const_iterator start = input.begin();
        std::string::const_iterator end   = input.end();
    
        while (boost::regex_search(start, end, what, r))
        {
            string stest(what[1].first, what[1].second);
            cout << stest << endl;
            // Update the beginning of the range to the character
            // following the whole match
            start = what[0].second;
        }
    
        // Alternate method using token iterator 
        const int subs[] = {1};  // we just want to see group 1
        boost::sregex_token_iterator i(input.begin(), input.end(), r, subs);
        boost::sregex_token_iterator j;
        while(i != j)
        {
           cout << *i++ << endl;
        }
    
        return 0;
    }
    

    输出:

    test1
    test2
    test3
    test0

    【讨论】:

      【解决方案2】:

      Boost.Regex 为这个特性提供了实验性支持(称为重复捕获);但是,由于它对性能的影响很大,因此默认情况下禁用此功能。

      要启用重复捕获,您需要重新构建 Boost.Regex 并在所有翻译单元中定义宏 BOOST_REGEX_MATCH_EXTRA;最好的方法是在 boost/regex/user.hpp 中取消注释这个定义(参见the reference,它位于页面的最底部)。

      使用此定义编译后,您可以通过调用/使用 regex_searchregex_matchregex_iteratormatch_extra 标志来使用此功能。

      查看参考Boost.Regex 了解更多信息。

      【讨论】:

        【解决方案3】:

        在我看来,您需要创建一个regex_iterator,使用(test[0-9]) 正则表达式作为输入。然后您可以使用生成的regex_iterator 来枚举原始目标的匹配子字符串。

        如果您仍然需要“一个整体匹配”,那么也许该工作必须与查找匹配子字符串的任务分离。你能澄清一下你的那部分要求吗?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-30
          • 2018-06-22
          • 2019-05-05
          • 2011-11-10
          • 2012-10-21
          • 1970-01-01
          相关资源
          最近更新 更多