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

时间:2012-11-23 10:11:05

标签: c++ regex boost c++11

  

可能重复:
  No matches with c++11 regex

之前我曾使用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,提升: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是正确的吗?

1 个答案:

答案 0 :(得分:7)

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

具体来说,boost.regex支持perl扩展listed here.,但你没有使用任何扩展名。{/ p>

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

clang的输出:

~ $ 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*?]无法匹配,这很快归结为匹配{{1}}与boost / visual studio ..我认为,这也是一个错误。