8

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);

为什么这场比赛会失败?

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

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

4

1 回答 1

5

我相信测试是正确的。在 re.alg 下的所有 libc++ 测试中搜索“锦标赛”,并比较不同引擎如何regex("tour|to|tournament")处理.regex_searchregex_match

让我们从regex_search

awk、egrep、扩展:

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

匹配整个输入字符串:“比赛”。

ECMA 脚本:

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

仅匹配输入字符串的一部分:“tour”。

grep,基本:

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

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

awk、egrep 和extended 将尽可能多地匹配交替。然而,ECMAScript 交替是“有序的”。这在ECMA-262中指定。一旦 ECMAScript 匹配交替中的一个分支,它就会退出搜索。该标准包括以下示例:

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

返回结果“a”而不是“ab”。

<plug>

Jeffrey EF Friedl 在 Mastering Regular Expressions中也对此进行了深入讨论。<regex>没有这本书,我不可能实现。我会坦率地承认,我对正则表达式的了解比我所知道的要多得多。

在关于交替的章节的最后,作者说:

如果您在第一次阅读本章时理解了本章中的所有内容,那么您可能一开始就没有阅读它。

相信它!

</plug>

无论如何,ECMAScript 只匹配“tour”。regex_match仅当整个输入字符串匹配时,该算法才返回成功。由于仅匹配输入字符串的前 4 个字符,因此与 awk、egrep 和扩展不同,ECMAScript 返回 false 和大小为零的cmatch.

于 2013-07-12T15:59:22.280 回答