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 str()
<h3>提取匹配位置和子串内容(<code>std::smatch</code> 成员)</h3>
<p><code>std::smatch</code> 不仅存子串值,还记录起始/结束位置,这对需要上下文或替换操作的场景很关键。它的 <code>[0]</code> 是整个匹配,<code>[1]</code> 起是捕获组。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
-
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+)"。
- 错误写法:
std::regex re("d+")→ 编译不过(d 是非法转义) - 危险写法:
std::regex re("\d+")→ 可编译,但易多写或少写反斜杠 - 推荐写法:
std::regex re(R"(d+)"),清晰且不易错 - 如果正则来自用户输入或配置文件,得额外做反斜杠预处理,否则可能崩溃或误匹配
std::regex_iterator 加 R"(...)" 就够了;真要重叠或高性能,就得换用 PCRE2 或 Boost.Regex,标准库在这块确实简陋。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










