30

私はこの質問に答えようとして正規表現を試していましたが、一致するものは見つかりましたregex_matchが、一致regex_searchしないことがわかりました。

次のプログラムは、g++ 4.7.1 でコンパイルされています。

#include <regex>
#include <iostream>

int main()
{
    const std::string s = "/home/toto/FILE_mysymbol_EVENT.DAT";
    std::regex rgx(".*FILE_(.+)_EVENT\\.DAT.*");
    std::smatch match;

    if (std::regex_match(s.begin(), s.end(), rgx))
        std::cout << "regex_match: match\n";
    else
        std::cout << "regex_match: no match\n";

    if (std::regex_search(s.begin(), s.end(), match, rgx))
        std::cout << "regex_search: match\n";
    else
        std::cout << "regex_search: no match\n";
}

出力:

regex_match: 一致
regex_search: 一致しません

両方が一致するはずであるという私の仮定は間違っていますか、それとも GCC 4.7.1 のライブラリに問題があるのでしょうか?

4

4 に答える 4

7

あなたの正規表現は、VS 2012rc で正常に動作します(両方とも一致します)。

g++ 4.7.1(-std=gnu++11)で、以下を使用する場合:

  • ".*FILE_(.+)_EVENT\\.DAT.*"regex_match一致しますが、一致regex_searchしません。
  • ".*?FILE_(.+?)_EVENT\\.DAT.*"、どちらregex_matchともregex_search一致しません (O_o)。

すべてのバリアントが一致する必要がありますが、一致しないものもあります ( betabandidoによって既に指摘されている理由により)。g++ 4.6.3(-std=gnu++0x)では、動作は g++ 4.7.1 と同じです。

ブースト (1.50)は、両方のパターンのバリエーションですべてを正しく一致させます。

まとめ

                        regex_match regex_search
 -------------------------------------------------- ---
 g++ 4.6.3 Linux OK/- -
 g++ 4.7.1 Linux OK/- -
 vs 2010 OK OK
 vs 2012rc OK OK
 ブースト 1.50 勝利 OK OK
 ブースト 1.50 linux OK OK
 -------------------------------------------------- ---

あなたのパターンに関しては、ドット文字を意味'.'する場合は、そう書く必要があります ( "\\.")。?貪欲でない修飾子 ( )を使用して、バックトラックを減らすこともできます。

".*?FILE_(.+?)_EVENT\\.DAT.*"
于 2012-07-24T10:58:53.517 に答える
7

C++ とBoost Regexの構造と機能は似ていると仮定すると、regex_matchとの違いregex_searchは次のとおりです

regex_match()正規表現が最初から最後まで入力全体と一致する場合にのみ、アルゴリズムは成功を報告します。正規表現が入力の一部のみに一致する場合は、regex_match()false を返します。正規表現が一致する部分文字列を探して文字列を検索する場合は、regex_search()アルゴリズムを使用します。

于 2015-05-08T10:22:24.880 に答える
4

の最新の libstdc++ソース コードregex_search調べると、次のことがわかります。

* @todo Implement this function.

残念ながら、残っている TODO アイテムはこれだけではありません。GCC の<regex>実装は現在不完全です。#ifdefGCC が追いつくまでは、Boost または Clang とコードを使用することをお勧めします。

(これは 4.8 ブランチでも修正されていません。)

于 2012-07-24T16:16:31.243 に答える
2

C++11 で正規表現ライブラリを使用しようとしましたが、多くの問題が発生しました (g++ 4.6 と 4.7 の両方を使用)。基本的に、サポートがないか、部分的なサポートしかありません。それは SVN バージョンにも当てはまります。ここに libstdc++ の SVN バージョンの現在のステータスを説明するリンクがあります。

というわけで、当面はBoost.Regexを使い続けるのが一番だと思います。

または、 libc++を使用してみてください。このドキュメントによると、正規表現のサポートは完全です。

于 2012-07-24T10:03:54.603 に答える