【问题标题】:Retrieving the results from the std::tr1::regex_search从 std::tr1::regex_search 检索结果
【发布时间】:2014-01-09 09:18:35
【问题描述】:

在 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?我怎么知道哪个对象会产生预期的结果?

谢谢 苏尼尔

【问题讨论】:

    标签: regex tr1


    【解决方案1】:

    here所述:

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

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

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

    看到包含测试字符串的文本字段中的两种颜色了吗?
    绿色是您的捕获组的背景,而
    蓝色代表通常与表达式匹配但未被任何组捕获的所有其他内容。
    换句话说:在你的情况下,蓝色+绿色相当于match[0],绿色相当于match[1]

    这样你总能知道match中的哪些对象指的是哪个捕获组:
    您在脑海中初始化一个计数器,从 0 开始。现在从左到右遍历正则表达式,为每个 ( 添加 1,为每个 ) 减去 1,直到到达捕获组的左括号想提取。你脑子里的数字就是数组索引。

    编辑
    关于您对检查res[0].first的评论:

    sub_match类的成员first只有

    表示比赛开始的位置。

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

    考虑以下程序 (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 为我们提供了从匹配开始到匹配结束的子字符串,输出不应该再令人困惑了。

    【讨论】:

    • 考虑一下。源 = "abcdabcdabcd" 和 exp = "ab"。该工具以蓝色突出显示 ab。但是,当我使用正则表达式执行此代码时,结果大小为 1。它 res[0].first 是“abcdabcdabcd”。我相信“abcdabcdabcd”上的正则表达式“ab”应该返回“ab”。这里有什么问题?
    • 这里的错误是你打电话给res[0].first。查看res[0]的内容:是ab
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    • 2021-07-31
    • 2014-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多