C++20可用std::erase直接删除所有括号,安全高效;C++11需用std::remove_if+erase配合lambda;仅删圆括号时优先用std::remove;正则替换不适用于简单字符删除。

用 std::erase 删除所有括号(C++20 及以上)
如果你的编译器支持 C++20,最简洁的方式是直接调用 std::erase,它能原地移除容器中所有匹配值:
std::string s = "a(b)c[d]e{f}g";
std::erase(s, '(');
std::erase(s, ')');
std::erase(s, '[');
std::erase(s, ']');
std::erase(s, '{');
std::erase(s, '}');
// s 现在是 "abcdefg"
注意:std::erase 是针对 std::basic_string 的重载函数,不是通用算法;它比手写循环更安全、更高效,且不会因迭代器失效出错。
常见错误:误用 std::remove + erase 组合但忘记调用 erase —— 这只会把括号移到末尾,字符串长度不变。
兼容 C++11 的通用写法:用 std::remove_if + erase
对老标准项目,推荐用 std::remove_if 配合 lambda 判断括号字符:
立即学习“C++免费学习笔记(深入)”;
std::string s = "a(b)c[d]e{f}g";
s.erase(
std::remove_if(s.begin(), s.end(), [](char c) {
return c == '(' || c == ')' ||
c == '[' || c == ']' ||
c == '{' || c == '}';
}),
s.end()
);
关键点:
-
std::remove_if不真正删除,只重排元素并返回新逻辑结尾迭代器 - 必须配对使用
erase(..., s.end())才能真正缩短字符串 - lambda 中用
||连接判断比查表或std::string::find更快,无额外内存开销
如果只要删圆括号,别误删其他括号类型
很多需求其实只针对 ( 和 ),比如解析数学表达式或清理日志。这时别一股脑删所有括号,否则可能破坏 JSON 或路径字符串里的 [、{。
正确做法是显式限定范围:
s.erase(std::remove(s.begin(), s.end(), '('), s.end());
s.erase(std::remove(s.begin(), s.end(), ')'), s.end());
性能提示:对单个字符,std::remove 比 std::remove_if 略快,因为无需调用函数对象;且可读性更强,意图明确。
容易踩的坑:写成 s = std::regex_replace(s, std::regex(R"([\(\)])"), "") —— 正则在简单字符替换场景下开销大、可读差、还引入异常风险。
需要保留括号内容、只删括号符号本身?
比如把 "func(x, y)" 变成 "funcx, y",而不是 "funcxy" —— 这说明你实际想做的是“剥离括号,但不合并相邻字符”。此时不能用全局删除,得用遍历+条件拼接:
std::string s = "func(x, y)";
std::string result;
result.reserve(s.size()); // 预分配避免多次扩容
for (char c : s) {
if (c != '(' && c != ')') {
result += c;
}
}
// result 是 "funcx, y"
注意点:
- 预分配
reserve在长字符串时明显提升性能 - 不要用
std::stringstream拼接——小字符串下构造/析构开销反而更高 - 如果需处理嵌套或配对逻辑(如只删最外层括号),那就超出“删除所有括号”范畴,得上栈或递归解析了
最常被忽略的是:没确认清楚需求到底要不要保留空格或换行——比如 "hello\n(world)" 删完括号后,\n 还在,但有人会误以为“删括号=删整段”。这类边界得靠输入样例提前对齐。


















