在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?我怎么知道哪个对象会产生预期的结果呢?
由于 苏尼
答案 0 :(得分:0)
如上所述here:
匹配[0]:代表整场比赛
match [1]:代表第一场比赛
match [2]:表示第二场比赛,依此类推
这意味着match[0]
应该 - 在这种情况下! - 在匹配整个内容时保留完整的source
(abcd 16000
),而match[1]
包含capturing group的内容。
例如,如果你的正则表达式中有第二个捕获组,你将在匹配集合中获得第三个对象,依此类推。
我是一个更了解可视化问题/解决方案的人,所以让我们这样做:
请参阅demo@regex101。
查看包含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
从比赛开始和比赛结束之后给出了我们的子串,输出不应该再混淆了。