从std :: tr1 :: regex_search中检索结果

时间:2014-01-09 09:18:36

标签: regex tr1

在std :: tr1 :: regex中运行函数regex_search后,我对如何获取结果感到困惑。 以下是演示我的问题的示例代码。

string source = "abcd 16000 ";
string exp = "abcd ([^\\s]+)";
std::tr1::cmatch res;
std::tr1::regex rx(exp);

while(std::tr1::regex_search(source.c_str(), res, rx,   std::tr1::regex_constants::match_continuous))
{

   //HOW TO FETCH THE RESULT???????????
   std::cout <<" "<< res.str()<<endl;

   source = res.suffix().str();
}

提到的正则表达式最好从字符串中删除“abcd”并返回16000。

我看到cmatch res有两个对象。第二个对象包含预期结果。(此对象有三个成员(匹配,第一个,第二个)。值为{true,“16000”,“”}。

我的问题是这个对象的大小表示什么?当我只运行一次regex_search时,为什么在这个特定情况下(res [0]和res [1])显示2?我怎么知道哪个对象会产生预期的结果呢?

由于 苏尼

1 个答案:

答案 0 :(得分:0)

如上所述here

  

匹配[0]:代表整场比赛
  match [1]:代表第一场比赛
  match [2]:表示第二场比赛,依此类推

这意味着match[0]应该 - 在这种情况下! - 在匹配整个内容时保留完整的sourceabcd 16000),而match[1]包含capturing group的内容。
例如,如果你的正则表达式中有第二个捕获组,你将在匹配集合中获得第三个对象,依此类推。

我是一个更了解可视化问题/解决方案的人,所以让我们这样做:
请参阅demo@regex101

enter image description here

查看包含teststring的文本字段中的两种颜色?
绿色是您的捕获组的背景 蓝色表示通常与表达式匹配的所有其他内容,但不会被任何组捕获 换句话说:蓝色+绿色相当于match[0],绿色代表match[1]

通过这种方式,您始终可以知道match中的哪些对象指的是哪个捕获组:
你从头开始初始化一个计数器。现在从左到右遍历正则表达式,为每个(加1并为每个)减1,直到你到达要提取的捕获组。头脑中的数字是数组索引。

修改
关于您对检查res[0].first

的评论

first类的成员sub_match仅为

  

表示比赛开始的位置。

虽然second表示比赛结束的位置 (取自boost doc
两者都返回char*(VC ++ 10)或iterator(Boost),因此您获得sourcetring的子字符串作为输出(如果匹配从index开始,则可能是完整的源零!)。

考虑以下程序(VC ++ 10):

#include "stdafx.h"
#include <regex>
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    string source = "abcdababcdefg";
    string exp = "ab";
    tr1::cmatch res;
    tr1::regex rx(exp);

    tr1::regex_search(source.c_str(), res, rx);

    for (size_t n = 0; n < res.size(); ++n) 
    { 
        std::cout << "submatch[" << n << "]: matched == " << std::boolalpha 
            << res[n].matched << 
            " at position " << res.position(n) << std::endl; 
        std::cout << "  " << res.length(n) 
            << " chars, value == " << res[n] << std::endl; 
    }
    std::cout << std::endl; 

    cout << "res[0].first: " << res[0].first << " - res[0].second: " << res[0].second << std::endl;
    cout << "res[0]: " << res[0];

    cin.get();

    return 0;
}

执行它并查看输出。第一个(也是唯一一个)匹配 - 显然 - 第一个匹配ab,所以这实际上是整个匹配的字符串以及res[0] == "ab"的原因。 现在,知道.first / .second从比赛开始和比赛结束之后给出了我们的子串,输出不应该再混淆了。