在libc++上,为什么regex_match("tournament",regex("tour|to|tournament"))失败?
On libc++, why does regex_match("tournament", regex("tour|to|tournament")) fail?
Inhttp://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++上,匹配才会失败。
我相信测试是正确的。在re.alg下的所有libc++测试中搜索"锦标赛",并比较不同的引擎如何处理regex("tour|to|tournament")
,以及regex_search
与regex_match
的不同,这很有指导意义。
让我们从regex_search
:开始
awk,egrp,扩展:
regex_search("tournament", m, regex("tour|to|tournament"))
匹配整个输入字符串:"锦标赛"。
ECMAScript:
regex_search("tournament", m, regex("tour|to|tournament"))
只匹配输入字符串的一部分:"tour"。
grep,基本:
regex_search("tournament", m, regex("tour|to|tournament"))
根本不匹配。"|"字符并不特殊。
awk、egrp和extended将通过交替尽可能多地匹配。但是ECMAScript的替换是"有序的"。这在ECMA-262中有规定。一旦ECMAScript匹配了替换中的一个分支,它就会退出搜索。该标准包括以下示例:
/a|ab/.exec("abc")
返回结果"a"而不是"ab"。
<plug>
Jeffrey E.F.Friedl在《掌握正则表达式》一书中也对此进行了深入讨论。如果没有这本书,我不可能实现<regex>
。我会坦率地承认,关于正则表达式,我所不知道的还有很多,而不是我所知道的。
在关于交替的章节末尾,作者指出:
如果你第一次阅读时就理解了这一章的所有内容你可能一开始就没读过。
相信它!
</plug>
无论如何,ECMAScript只匹配"tour"。只有整个输入字符串匹配时,regex_match
算法才会返回成功。由于只有输入字符串的前4个字符匹配,因此与awk、egrp和extended不同,ECMAScript返回false,cmatch
大小为零。
- 此模式的C++RegEx
- C++ std::regex 使用前瞻失败
- std::regex:匹配由数字和空格组成的字符串,并提取数字.如何?
- 使用 boost::regex 从目录中获取带有一些正则表达式的文件名称时出现意外输出
- 你能防止 std::regex 在无效表达式上抛出异常吗?
- 使用Regex解析cpp中的字符串并创建映射
- C++:如何用split查找单词?Regex
- 在VC2015U3上,std::regex比boost::regex慢得多
- 是否有更有效的方法来生成日期的REGEX字符串
- 在C++中使用带有regex的捕获组
- 将std::regex设置为静态的好主意吗
- 为什么Regex(c++)需要指数时间
- std::regex and dual ABI
- C++11 std::regex后备选项
- 以不同的方式替换每一项,regex c++
- 使用 boost::regex (c++) 比较两个正则表达式
- Build Boost Regex for Windows VS2013
- 包含在 std::regex 搜索中,使用 std::regex_token_iterator 从 std::sub_m
- std::string references、std::regex和boost::filesystem的基本概念
- 在libc++上,为什么regex_match("tournament",regex("tour|to|tournament"))失败?