如何让std::regex_search返回所有匹配(类似Perl的g修饰符)
问题
在Perl的正则引擎中,使用g修饰符可以返回所有匹配的子串实例,例如以下代码:
my $data = "one two three four"; my @result = ($data =~ /(\w+)/g); say "@result";
输出:
one two three four
但使用C++的std::regex_search时,仅能返回第一个匹配,示例代码如下:
std::string srchStr = "one two three four"; std::regex r("(\\w+)"); std::smatch m; if (regex_search(srchStr, m, r)) { std::cout << "m.size()=" << m.size() << std::endl; for (const std::string &s : m) { std::cout << s << std::endl; } }
输出:
m.size()=2 one one
请问C++中是否存在类似Perl里g操作符的机制,能让std::regex_search返回所有匹配?
解决方案
C++标准库没有给std::regex_search提供类似Perlg修饰符的直接参数,但可以通过两种方式实现全局匹配:
1. 循环调用std::regex_search
std::regex_search默认仅查找第一个匹配,我们可以通过每次更新搜索的起始位置,循环调用它来获取所有匹配。每次匹配完成后,利用std::smatch的suffix()方法获取当前匹配之后的剩余字符串起始位置,作为下一次搜索的起点:
#include <iostream> #include <string> #include <regex> int main() { std::string srchStr = "one two three four"; std::regex r("(\\w+)"); std::smatch m; auto search_start = srchStr.cbegin(); while (std::regex_search(search_start, srchStr.cend(), m, r)) { std::cout << m[1] << std::endl; // 输出捕获组的内容 search_start = m.suffix().first; // 更新搜索起始位置 } return 0; }
2. 使用std::sregex_iterator(更简洁的方式)
std::sregex_iterator是专门用于遍历字符串中所有正则匹配的迭代器,它的工作方式和Perl的g修饰符效果一致,会自动遍历所有匹配结果:
#include <iostream> #include <string> #include <regex> int main() { std::string srchStr = "one two three four"; std::regex r("(\\w+)"); // 构造迭代器,遍历所有匹配 for (std::sregex_iterator it(srchStr.begin(), srchStr.end(), r), end_iter; it != end_iter; ++it) { std::cout << (*it)[1] << std::endl; } return 0; }
另外补充说明:原代码中m.size()=2是因为std::smatch中同时保存了整个匹配的子串(m[0])和捕获组的内容(m[1]),所以两个输出都是one。
内容的提问来源于stack exchange,提问作者Paul CyberCitizen
相关产品推荐
相关产品推荐

