2013-07-12 4 views
8

は、 次のテストが存在します。libC++では、なぜregex_match( "tournament"、regex( "tour | to | tournament"))が失敗するのですか? <a href="http://llvm.org/svn/llvm-project/libcxx/trunk/test/re/re.alg/re.alg.match/ecma.pass.cpp">http://llvm.org/svn/llvm-project/libcxx/trunk/test/re/re.alg/re.alg.match/ecma.pass.cpp</a>で

std::cmatch m; 
    const char s[] = "tournament"; 
    assert(!std::regex_match(s, m, std::regex("tour|to|tournament"))); 
    assert(m.size() == 0); 

はなぜ、この試合は失敗しなければなりませんか?

VC++ 2012および追加で、この試合は成功します。
ChromeとFirefoxのJavascriptでは"tournament".match(/^(?:tour|to|tournament)$/)が成功します。

libC++でのみ、一致が失敗します。

+0

私のテストでは。 'c'は'(a | b)| c'と 'a |(b | c)'と一致しますが、 'a | b | c'とは一致しません。 'a'と' b'は3つとも一致します。一般に、2つ以上の式が '| 'で連結されている場合、最初の2つの式だけが動作するように見えます。私はそれがバグだと思うが、何らかの理由でこのテストを "ecma.pass.cpp"と呼ぶので、わからない。 –

+0

[こちら](http://stackoverflow.com/questions/9764264/strange-bug-stdregex-matches-only-first-two-strings)は同じことの別のレポートです。 –

+1

Hmm。これはバグ報告が必要だと思う。実際に正しい場合でも、テストは*なぜ*正しいのかを記録する必要があります。そして、私はそれが疑わしい。 –

答えて

5

私はテストが正しいと信じています。 re.algのすべてのlibC++テストで「トーナメント」を検索し、異なるエンジンがregex("tour|to|tournament")をどのように扱い、どのようにregex_searchregex_matchと異なるのかを比較することは有益です。

のはregex_searchを見てみましょう:

のawk、egrepを、拡張された: "トーナメント":

regex_search("tournament", m, regex("tour|to|tournament")) 

は、入力文字列全体にマッチします。

のECMAScript:

regex_search("tournament", m, regex("tour|to|tournament")) 

一致した入力文字列の一部のみ: "ツアー"。

基本的なgrepを、:

regex_search("tournament", m, regex("tour|to|tournament")) 

は全く一致していません。 '|'文字は特別ではありません。

awk、egrepとextendedは、可能な限り交互に一致します。ただし、ECMAScriptの変更は「順序付け」されています。これはECMA-262で指定されています。 ECMAScriptは、交替内のブランチと一致すると、検索を終了します。

/a|ab/.exec("abc") 

戻り結果 "" なく、 "AB":標準は、この例を含みます。

<plug>

これはまた、Mastering Regular Expressions by Jeffrey E.F. Friedlで徹底的に議論されています。この本がないと<regex>を実装できませんでした。そして私は、私が知っているよりも、私が正規表現について知らないことがまだまだたくさんあることを、自由に認めます。交替の章著者状態の終わりに

あなたは、この章では、あなたが それを読んで初めて、すべてを理解している場合、あなたはおそらく最初の場所でそれを読んでいません。

それを信じてください!

</plug>

とにかく、ECMAScriptのは、唯一の "ツアー" にマッチします。 regex_matchアルゴリズムは、の入力文字列全体がの場合にのみ成功します。入力文字列の最初の4文字のみが一致するため、awk、egrep、およびextendedとは異なり、ECMAScriptはゼロサイズのcmatchでfalseを返します。

+0

あなたの説明は正しいかもしれませんが、正規表現の全体的な目的、具体的には交替の目的は疑わしいでしょう。それがあなたのようなものなら、そのような行動から得られるものは何ですか? –

+0

私は間違った人物です。私は正規表現の専門家でもなく、正規表現エンジンの設計や、 'std :: regex'のC++標準化にも参加していません。標準化された後に 'std :: regex'を実装しました。 –

+0

'regex_match' **は' regex_search'とまったく同じように動作する必要があります** **(regex_searchのように一部だけではなく)与えられた文字列全体と**合致するようなさらなる制約があります。上の例の*不一致*はすべての大会とすべての期待に矛盾します(私はすべてのフリードルの本を読んで、毎日のベースで正規表現を使用しました)。 –

関連する問題