无法检索正则表达式匹配结果 - MFC / C ++

时间:2016-02-11 18:25:24

标签: c++ regex mfc format-specifiers

我正在阅读HTML页面并尝试检索其中的特定字符串。

我有以下代码:

    std::string str = test.GetString(); // someString ( the string i have checked it, it's basically an html page )
    std::smatch match;
    std::regex re("0x(\\d|[A-Z]).*0000"); // the pattern I'm searching for
    if (std::regex_search(str, match, re)){
        test = "found"; // found gets printed
    }
    TRACE("%s\n",match[0]); // this outputs some garbage like this '˜ò'

我想打印/存储找到的匹配结果,但我得到了一些垃圾。

免责声明:我是C ++正则表达式的新手。我可能会犯一个基本的错误

2 个答案:

答案 0 :(得分:3)

std::smatch match;
...
TRACE("%s\n",match[0]); // this outputs some garbage like this '˜ò'

%s宏中的 TRACE 类型说明符需要ANSI / MBCS版本中的原始C字符串指针char* ; wchar_t*在Unicode版本中 - 我假设您在这里进行ANSI / MBCS构建。)。

但是match[0] 不是原始C字符串指针。

因此,您通过TRACE承诺%s(即原始C字符串char*指针)与您实际 之间的不匹配传递给它(即match[0])。

根据some online documentationstd::smatchstd::match_results模板的特化,特别是:

smatch --> match_results<string::const_iterator>

smatch::operator[](您在代码中调用match[0]returns a reference to another object,这是std::sub_match。 此std::sub_match class表示一对迭代器,表示匹配字符的序列。

所以,你承诺TRACE传递一个原始的C字符串指针(通过%s类型说明符),但你实际上是在传递一个不同的东西,即对std::sub_match对象的引用(通过你的match[0]代码):难怪打印的文本毫无意义。

您需要做的是从match[0]表达式获取C字符串指针。

为此,您可以调用std::sub_match's str() method。这会返回 std::string 对象。

但是,这个std::string对象正是%s所期望的:实际上,%s表示原始C字符串指针(例如const char* }),一个std::string实例。

所以,最后一步是从std::string对象中提取这个原始C字符串指针,这是通过调用std::string::c_str() method完成的。

总结这些逻辑步骤:

std::smatch match;
...
match[0]               --> reference to std::sub_match object
match[0].str()         --> std::string object
match[0].str().c_str() --> raw C string pointer (const char*)

因此,您的TRACE语句可以写成:

TRACE("%s\n", match[0].str().c_str());

答案 1 :(得分:2)

这里的问题是match[0]返回类型为sub_match的对象,它只是一对迭代器。如果TRACE宏的第一个参数是C样式格式说明符,请将sub_match对象转换为C字符串,如下所示:

TRACE("%s\n", std::string(match[0]).c_str());

即,使用sub_match&#39; s operator string()获取(临时)C ++字符串对象,然后调用其成员函数c_str()以获取(临时)C字符串对象。