std::regex_iterator 是遍历所有匹配项最标准可控的方式,它跳过重叠匹配、逐个返回 std::smatch,需传入 std::string 的 begin()/end() 迭代器,正则建议用 R"(...)" 声明并复用。

用 std::regex_iterator 遍历所有匹配项
直接用 std::regex_iterator 是最标准、最可控的方式,它会跳过重叠匹配(C++ 标准库不支持重叠匹配),逐个返回 std::smatch。注意它要求输入是 std::string::const_iterator,不是 C 风格字符串指针。
- 必须传入
std::string的begin()和end(),不能传c_str() - 正则对象建议复用,避免重复编译开销;若正则固定,可声明为
static const std::regex - 匹配失败时迭代器直接等于
end,无需额外判空
std::string s = "a123b456c789";
std::regex re(R"(d+)");
for (std::sregex_iterator it(s.begin(), s.end(), re), end; it != end; ++it) {
std::cout << it->str() << "
"; // 输出: 123, 456, 789
}
提取匹配位置和子串内容(std::smatch 成员)
std::smatch 不仅存子串值,还记录起始/结束位置,这对需要上下文或替换操作的场景很关键。它的 [0] 是整个匹配,[1] 起是捕获组。
-
match.str(0)或match.str()获取完整匹配文本 -
match.position(0)返回匹配在原字符串中的起始索引(size_t) -
match.length(0)是匹配长度,可用于计算结束位置:match.position() + match.length() - 若正则含括号捕获组但未匹配到,访问
match[i]会触发未定义行为——务必先用match.size() > i判断
处理重叠匹配(标准库不支持,需手动滑动)
C++ 标准库的 std::regex 实现不支持重叠匹配(比如在 "aaaa" 中找 "aa",只返回位置 0 和 2,跳过 1 和 3)。真有这需求,得自己写循环 + std::regex_search。
- 每次从上一次匹配的
position + 1开始搜索,而不是+ length - 用
std::regex_search(start_iter, end_iter, match, re),并更新start_iter = match[0].first + 1 - 性能明显下降,尤其长字符串+短模式时;如非必要,避免这种写法
常见错误:忘记转义反斜杠或使用原始字符串字面量
写正则时漏掉一个反斜杠,结果就变成匹配字面量 d 而不是“数字”,这是最常踩的坑。C++ 字符串里 是转义符,所以 "\d+" 才等价于正则的 d+;更安全的是用原始字符串 R"(d+)"。
立即学习“C++免费学习笔记(深入)”;
- 错误写法:
std::regex re("d+")→ 编译不过(d 是非法转义) - 危险写法:
std::regex re("\d+")→ 可编译,但易多写或少写反斜杠 - 推荐写法:
std::regex re(R"(d+)"),清晰且不易错 - 如果正则来自用户输入或配置文件,得额外做反斜杠预处理,否则可能崩溃或误匹配
std::regex_iterator 加 R"(...)" 就够了;真要重叠或高性能,就得换用 PCRE2 或 Boost.Regex,标准库在这块确实简陋。


















