我有以下代码:
int main()
{
regex reg_expr("(\\([A-Z],[A-Z]\\))(?:\\s(\\([A-Z],[A-Z]\\)))*");
//regex reg_expr("(\\([A-Z],[A-Z]\\))(?:\\s(\\([A-Z],[A-Z]\\)))*\\s(\\([A-Z],[A-Z]\\))");
smatch sm;
string input("(A,B) (C,D) (F,W) (G,K) (R,M)");
//string input("(A,B) (C,D) (F,W)");
if (regex_match(input, sm, reg_expr)) {
cout << "true\n";
cout << sm.size() << "\n";
for (int i = 0; i < sm.size(); i++) {
//if (sm[i].length())
cout << "submatch number " << i << ": " << sm[i].str() << '\n';
}
} else
cout << "false";
return 0;
}
除了“smatch sm”对正则表达式字符串中指定的每个子表达式只有一个子字符串外,一切正常。 例如,对于以下测试字符串:
(A,B) (C,D) (F,W) (G,K) (R,M)
与
正确匹配 (\([A-Z],[A-Z]\))(?:\s(\([A-Z],[A-Z]\)))*
正则表达式,“sm”只有树子串:一个用于整个字符串,另外两个是“(A,B)”和“(R,M)”,“(C,D) “,”(F,W)“,”(G,K)“缺失,但它们匹配。
看起来正则表达式(?:\s(\([A-Z],[A-Z]\)))*
正确理解0个或更多个子表达式应该匹配,但似乎只有一个子表达式存储在std::smatch sm
中。<登记/>
这是一个库错误(不太可能)或我做错了什么?你的帮助和建议很好!
答案 0 :(得分:2)
这不是一个bug,但几乎是一个普遍的行为(除了PyPi Python regex
模块,.NET和(如果使用适当的选项编译)Boost)当重复捕获时只将最后匹配的项存储在其缓冲区中
有关详情,请参阅Repeating a Capturing Group vs. Capturing a Repeated Group文章。
在您的情况下,您可以使用常规std::sregex_iterator
:
int main() {
std::regex reg_expr(R"(\([A-Z],[A-Z]\))");
string input("(A,B) (C,D) (F,W) (G,K) (R,M)");
for(std::sregex_iterator i = std::sregex_iterator(input.begin(), input.end(), reg_expr);
i != std::sregex_iterator();
++i)
{
std::cout << (*i).str() << std::endl;
}
return 0;
}
请参阅C++ demo
注意我使用的是原始字符串文字R"(...)"
,其中只需要1个反斜杠来转义正则表达式元字符。