5

Possible Duplicate:
No matches with c++11 regex

I was using boost::regex for some stuff before and for some new stuff I wanted to use std::regex until I noticed the following inconsistency - so question is which one is correct?

#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.*.*.*.*");
}

For me (gcc 4.7.2, -std=c++11, boost: 1.51), I see the following:

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

If I change the pattern to a greedy pattern (.*), then I see:

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

Which one to believe? I would guess that boost is correct here?

4

1 回答 1

8

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 不同的匹配。我认为这也是一个错误。

于 2012-11-26T00:33:25.970 回答