c++oding="utf-8" ?>
c++20起应优先用std::erase(s, '{')和std::erase(s, '}')原地安全删除所有花括号;旧标准需用std::remove_if配合erase;正则和string_view处理仅适用于特定场景。

用 std::erase 删除所有 { 和 }
C++20 起,std::string 支持直接用 std::erase 移除所有匹配字符,最简且安全。它原地修改、不需手动管理迭代器,也不会因 erase 导致迭代器失效问题。
常见错误是仍用老式循环 + erase(),比如:
for (auto it = s.begin(); it != s.end(); ++it) {
if (*it == '{' || *it == '}') s.erase(it); // ❌ it 失效,行为未定义
}
正确做法:
- 包含
<string></string>(C++20) - 对每个花括号分别调用:
std::erase(s, '{');和std::erase(s, '}'); - 顺序无关,两次调用性能开销线性,实际很快
兼容 C++11/14/17:用 std::remove_if + erase 惯用法
若项目不能用 C++20,必须用「remove-erase 惯用法」。注意不是 std::remove(只支持单值),而是 std::remove_if 配合 lambda 判断。
典型误写是漏掉最后的 erase:
std::remove_if(s.begin(), s.end(), [](char c) { return c == '{' || c == '}'; });
// ❌ 字符只是前移,尾部残留,长度没变
完整写法:
auto new_end = std::remove_if(s.begin(), s.end(), [](char c) { return c == '{' || c == '}'; });s.erase(new_end, s.end());- lambda 中用
||同时覆盖两种花括号,比两次 remove_if 更高效
正则替换(std::regex_replace)适合复杂模式,但别为简单需求用
如果后续要扩展成「去掉花括号及其内部内容」或「只去外层花括号」,正则才值得考虑。纯删字符时,它明显更慢、编译开销大、跨平台行为稍异(尤其 MinGW 对 std::regex 支持弱)。
最小可用示例:
s = std::regex_replace(s, std::regex("[{} ]"), ""); // 空格也一并去(可选)
注意事项:
- 必须包含
<regex></regex> - 方括号内写
[{}]表示匹配任一字符;写{|}也可,但需双转义("\{|\}") - MSVC 和 libc++ 实现较稳;libstdc++(GCC 默认)的
std::regex性能差,慎用于高频调用
别忽略字符串视图(std::string_view)场景
如果输入是 std::string_view(比如函数参数),它不可修改。此时不能原地删,得先转 std::string 再处理,或用算法构造新视图(但花括号位置不连续,无法用单个 view 表达)。
例如:
std::string clean(const std::string_view sv) {
std::string s(sv); // 必须拷贝
std::erase(s, '{');
std::erase(s, '}');
return s;
}
关键点:
-
std::string_view本身没有erase或remove_if成员 - 若追求零拷贝,只能手写遍历 + 构建新
std::string(用 reserve 预分配避免多次扩容) - 别试图用
substr拼接——花括号散落各处,成本更高
std::erase 就够了;剩下那些得兼容旧标准的,remove_if + erase 是唯一稳妥选择。正则和 string_view 处理都属于有明确前提才该动的分支。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











