5

重複の可能性:
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、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ここで正しいと思いますか?

4

1 に答える 1

8

もちろん、gcc は tr1/c++11 正規表現をサポートしていませんが、より一般的な答えを得るために、ドキュメントによると、boost.regex のデフォルトはperl 5ですが、C++ のデフォルトはECMAScriptであり、いくつかのロケール依存要素によって拡張されています。 POSIX BRE の。

具体的には、boost.regex は、ここにリストされている perl 拡張機能をサポートしています。、しかしあなたはそれらのどれも使用していません。

さて、気になったので、さらに 2 つのコンパイラでテストを実行しました。

クランからの出力:

~ $ 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 からの出力 (sans boost)

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 の不一致を詳しく見てみると、2 番目のテストではパターンが一致し、一致[FOO\.\*.*?]しませんでした。これはすぐに、boost/visual studio とは異なる方法で一致することになります..これもバグだと思います。[FOO.*][.*.*.*][S*?]

于 2012-11-26T00:33:25.970 に答える