在libc ++上,为什么regex_match("锦标赛",正则表达式("tour | to | tournament"))会失败?

gan*_*are 8 c++ regex c++11 libc++

http://llvm.org/svn/llvm-project/libcxx/trunk/test/re/re.alg/re.alg.match/ecma.pass.cpp中,存在以下测试:

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

为什么这场比赛会失败?

在VC++ 2012和boost上,匹配成功.
在Chrome和Firefox的Javascript上,"tournament".match(/^(?:tour|to|tournament)$/)成功.

仅在libc ++上,匹配失败.

How*_*ant 5

我相信测试是正确的.这是有益的搜索所有下re.alg提供的libc ++测试的"赛事",并比较不同的引擎如何对待regex("tour|to|tournament"),如何regex_search从不同的regex_match.

让我们从regex_search:

awk,egrep,扩展:

regex_search("tournament", m, regex("tour|to|tournament"))
Run Code Online (Sandbox Code Playgroud)

匹配整个输入字符串:"锦标赛".

ECMAScript中:

regex_search("tournament", m, regex("tour|to|tournament"))
Run Code Online (Sandbox Code Playgroud)

仅匹配输入字符串的一部分:"tour".

grep,基本:

regex_search("tournament", m, regex("tour|to|tournament"))
Run Code Online (Sandbox Code Playgroud)

根本不匹配.'|' 性格并不特别.

awk,egrep和extended将尽可能多地匹配交替.但ECMAScript交替是"有序"的.这在ECMA-262中有详细说明.一旦ECMAScript与交替中的分支匹配,它就会退出搜索.该标准包括以下示例:

/a|ab/.exec("abc")
Run Code Online (Sandbox Code Playgroud)

返回结果"a"而不是"ab".

<plug>

Jeffrey EF Friedl掌握正则表达式中也对此进行了深入讨论.<regex>没有这本书,我无法实现.而且我会坦然承认,除了我所知道的,还有更多我不了解的正则表达式.

在关于轮换的章节结束时,作者说:

如果您在第一次阅读本章时理解了本章的所有内容,那么您可能首先没有阅读它.

相信它!

</plug>

无论如何,ECMAScript只匹配"巡演".regex_match仅当整个输入字符串匹配时,算法才会返回成功.由于只输入字符串的前4个字符匹配,因此与awk,egrep和extended不同,ECMAScript以零大小返回false cmatch.

  • 霍华德,我不相信`regex_match`应该像你描述的那样表现.众所周知,标准中的描述不清楚.您可以根据"匹配正则表达式然后检查匹配是否跨越整个输入"来描述它.但它也可能意味着"匹配常规表达,就好像包含在^ .. $"中一样.我真的认为这里的措辞有很多不足之处. (3认同)
  • @SebastianRedl:我现在看到你描述的含糊不清.提交问题解决问题并不是一个坏主意.http://cplusplus.github.io/LWG/lwg-active.html#submit_issue (2认同)
  • 我现在相信你对"匹配"的解释不符合标准而另一个符合标准.但是,这个空间很小,但却包含一个参数. (2认同)