这是代码:
#include <string>
#include <regex>
#include <iostream>
int main()
{
std::string pattern("[^c]ei");
pattern = "[[:alpha:]]*" + pattern + "[[:alpha:]]*";
std::regex r(pattern);
std::smatch results;
std::string test_str = "cei";
if (std::regex_search(test_str, results, r))
std::cout << results.str() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
cei
Run Code Online (Sandbox Code Playgroud)
使用的编译器是gcc 4.9.1.
我是一个学习正则表达式的新手.我期望什么都不应该输出,因为"cei"这里的模式不匹配.我做得对吗?有什么问题?
更新:
这个已被报告并确认为错误,详情请访问:https: //gcc.gnu.org/bugzilla/show_bug.cgi?id = 63497
这是实现中的一个错误。我尝试过的其他几个工具不仅同意您的模式与您的输入不匹配,而且我尝试了以下方法:
#include <string>
#include <regex>
#include <iostream>
int main()
{
std::string pattern("([a-z]*)([a-z])(e)(i)([a-z]*)");
std::regex r(pattern);
std::smatch results;
std::string test_str = "cei";
if (std::regex_search(test_str, results, r))
{
std::cout << results.str() << std::endl;
for (size_t i = 0; i < results.size(); ++i) {
std::ssub_match sub_match = results[i];
std::string sub_match_str = sub_match.str();
std::cout << i << ": " << sub_match_str << '\n';
}
}
}
Run Code Online (Sandbox Code Playgroud)
这基本上与您所拥有的类似,但为了简单起见,我将其替换为[:alpha:],[a-z]并且我还暂时将其替换[^c]为[a-z],因为这似乎使其可以正常工作。这是它打印的内容(Linux x86-64 上的 GCC 4.9.0):
cei
0: cei
1:
2: c
3: e
4: i
5:
Run Code Online (Sandbox Code Playgroud)
如果我替换[a-z]你原来的位置[^c]并直接放在f那里,它会正确地表示模式不匹配。但如果我[^c]像你一样使用:
std::string pattern("([a-z]*)([^c])(e)(i)([a-z]*)");
Run Code Online (Sandbox Code Playgroud)
然后我得到这个输出:
cei
0: cei
1: cei
terminate called after throwing an instance of 'std::length_error'
what(): basic_string::_S_create
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
所以它声称匹配成功,结果[0]是“cei”,这是预期的。然后,结果[1]也是“cei”,我想这可能没问题。但随后 results[2] 崩溃了,因为它尝试用 begin=nullptr 构造一个std::stringof length 18446744073709551614。这个巨大的数字正是2^64 - 2,又名std::string::npos - 1(在我的系统上)。
所以我认为某处存在一个相差一的错误,其影响可能不仅仅是虚假的正则表达式匹配——它可能在运行时崩溃。