std :: regex_match&的区别的std :: regex_search?

时间:2014-11-02 05:06:59

标签: c++ regex c++11 visual-studio-2013 gcc4.9

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

Difference between regex_match and 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 

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

有人可以解释上面的例子,一般来说,使用这些方法的情况吗?

2 个答案:

答案 0 :(得分:23)

regex_match仅在整个输入序列匹配时返回true,而即使只有一个子序列与regex_search匹配,regex也会成功。

引自N3337,

  

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

  效果:确定正则表达式e所有字符序列[first,last) 之间是否匹配。 ...如果存在此类匹配,则返回true,否则返回false

以上描述适用于regex_match重载,它将一对迭代器与要匹配的序列相对应。剩余的重载是根据这种过载来定义的。

相应的regex_search重载被描述为

  

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

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


在您的示例中,如果您将regex修改为r{R"(.*?\s\d{2}\s.*)"};,则regex_matchregex_search都会成功(但匹配结果不仅仅是当天,而是整个日期字符串)。

Live demo您的示例的修改版本,其中regex_matchregex_search正在捕获并显示这一天。

答案 1 :(得分:14)

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

"one two three four"

如果我对表达式为regex_search的字符串使用"three",则会成功,因为"three"中可以找到"one two three four"

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