35

下面的程序已编写为使用 C++11 std::regex_matchstd::regex_search获取“Day”信息。但是,使用第一种方法返回false,第二种方法返回true(预期)。我阅读了与此相关的文档和已经存在的 SO 问题,但我不明白这两种方法之间的区别以及我们何时应该使用它们中的任何一种?对于任何常见问题,它们可以互换使用吗?

regex_match 和 regex_search 之间的区别?

#include<iostream>
#include<string>
#include<regex>

int main()
{
    std::string input{ "Mon Nov 25 20:54:36 2013" };
    //Day:: Exactly Two Number surrounded by spaces in both side
    std::regex  r{R"(\s\d{2}\s)"};
    //std::regex  r{"\\s\\d{2}\\s"};
    std::smatch match;

if (std::regex_match(input,match,r)) {
        std::cout << "Found" << "\n";
    } else {
        std::cout << "Did Not Found" << "\n";
    }

    if (std::regex_search(input, match,r)) {
        std::cout << "Found" << "\n";
        if (match.ready()){
            std::string out = match[0];
            std::cout << out << "\n";
        }
    }
    else {
        std::cout << "Did Not Found" << "\n";
    }
}

输出

Did Not Found

Found

 25 

为什么false在这种情况下第一个正则表达式方法返回?regex似乎是正确的,所以理想情况下两者都应该被退回true。我通过更改std::regex_match(input,match,r)to运行了上面的程序std::regex_match(input,r),发现它仍然返回false.

有人可以解释上面的例子,以及这些方法的一般用例吗?

4

2 回答 2

34

regex_matchtrue在匹配整个输入序列时返回,regex_search即使只有一个子序列匹配regex.

引自 N3337,

§28.11.2/2 regex_match [re.alg.match]

作用:e判断正则表达式和所有字符序列[first,last)是否匹配。如果存在这样的匹配则...返回,否则返回。truefalse

上面的描述是针对regex_match将一对迭代器带到要匹配的序列的重载。剩余的重载是根据这个重载来定义的。

相应的regex_search重载被描述为

§28.11.3/2 regex_search [re.alg.search]

效果:确定是否存在与正则表达式匹配的子序列[first,last)e。如果存在这样的序列,则...返回,否则。truefalse


在您的示例中,如果您将 修改regexr{R"(.*?\s\d{2}\s.*)"};bothregex_match并且regex_search将成功(但匹配结果不仅是日期,而且是整个日期字符串)。

您的示例的修改版本的现场演示,其中一天由regex_match和捕获并显示regex_search

于 2014-11-02T05:21:39.097 回答
19

这很简单。regex_search查看字符串以查找字符串的任何部分是否与正则表达式匹配。regex_match检查整个字符串是否与正则表达式匹配。作为一个简单的例子,给定以下字符串:

"one two three four"

如果我regex_search在该字符串上使用表达式"three",它将成功,因为"three"可以在"one two three four"

但是,如果我改用regex_match它,它将失败,因为"three"不是整个字符串,而只是其中的一部分。

于 2014-11-02T05:20:20.677 回答