boost::regex和std::regex之间的不一致



可能的重复项:
与 c++11 正则表达式不匹配

我之前曾将boost::regex用于某些东西,而对于我想使用的一些新东西std::regex直到我注意到以下不一致 - 所以问题是哪一个是正确的?

#include <iostream>
#include <regex>
#include <string>
#include <boost/regex.hpp>
void test(std::string prefix, std::string str)
{
  std::string pat = prefix + "\.\*.*?";
  std::cout << "Input   : [" << str << "]" << std::endl;
  std::cout << "Pattern : [" << pat << "]" << std::endl;
  {
    std::regex r(pat);
    if (std::regex_match(str, r))
      std::cout << "std::regex_match: true" << std::endl;
    else
      std::cout << "std::regex_match: false" << std::endl;
    if (std::regex_search(str, r))
      std::cout << "std::regex_search: true" << std::endl;
    else
      std::cout << "std::regex_search: false" << std::endl;
  }
  {
    boost::regex r(pat);
    if (boost::regex_match(str, r))
      std::cout << "boost::regex_match: true" << std::endl;
    else
      std::cout << "boost::regex_match: false" << std::endl;
    if (boost::regex_search(str, r))
      std::cout << "boost::regex_search: true" << std::endl;
    else
      std::cout << "boost::regex_search: false" << std::endl;
  }
}
int main(void)
{
  test("FOO", "FOO.*");
  test("FOO", "FOO.*.*.*.*");
}

对我来说(gcc 4.7.2,-std=c++11,boost:1.51),我看到以下内容:

Input   : [FOO.*]
Pattern : [FOO.*.*?]
std::regex_match: false
std::regex_search: false
boost::regex_match: true
boost::regex_search: true
Input   : [FOO.*.*.*.*]
Pattern : [FOO.*.*?]
std::regex_match: false
std::regex_search: false
boost::regex_match: true
boost::regex_search: true

如果我将模式更改为贪婪模式(.*),那么我会看到:

Input   : [FOO.*]
Pattern : [FOO.*.*]
std::regex_match: true
std::regex_search: false
boost::regex_match: true
boost::regex_search: true
Input   : [FOO.*.*.*.*]
Pattern : [FOO.*.*]
std::regex_match: true
std::regex_search: false
boost::regex_match: true
boost::regex_search: true

相信哪一个?我猜boost在这里是正确的?

gcc 当然不支持 tr1/c++11 正则表达式,但给出更通用的答案,boost.regex 的默认值是 perl 5,根据其文档C++默认值是 ECMAScript,由 POSIX BRE 的几个依赖于语言环境的元素扩展。

具体来说,boost.regex支持这里列出的perl扩展,但你没有使用其中任何一个。

现在,我很好奇,并通过另外两个编译器运行了您的测试:

叮当声的输出:

~ $ clang++ -o test test.cc -std=c++11 -I/usr/include/c++/v1 -lc++ -lboost_regex
~ $ ./test
Input   : [FOO.*]
Pattern : [FOO.*.*?]
std::regex_match: true
std::regex_search: true
boost::regex_match: true
boost::regex_search: true
Input   : [FOO.*.*.*.*]
Pattern : [FOO.*.*?]
std::regex_match: false
std::regex_search: true
boost::regex_match: true
boost::regex_search: true

Visual Studio 2012 的输出(无加速)

Input   : [FOO.*]
Pattern : [FOO.*.*?]
std::regex_match: true
std::regex_search: true
Input   : [FOO.*.*.*.*]
Pattern : [FOO.*.*?]
std::regex_match: true
std::regex_search: true

仔细观察 clang 的差异,在第二个测试中,它匹配的模式[FOO.*.*?] [FOO.*],而[.*.*.*]不匹配,这很快归结为匹配[S*?]与 boost/visual studio 不同......我认为这也是一个错误。