c++20推荐用std::erase(s, '"')一步删除双引号;c++11起通用方案是s.erase(std::remove(s.begin(), s.end(), '"'), s.end());避免regex_replace和手动循环,因性能差或易错。

用 std::erase 删除所有双引号(C++20)
如果你的编译器支持 C++20,std::erase 是最直接的方式:它原地修改字符串,语义清晰,且不会产生临时对象。
常见错误是误用 std::remove 单独调用——它只移动元素、不缩容,必须配对 erase 才真正删除;而 std::erase 一步到位。
std::string s = R"("hello" "world")";-
std::erase(s, '"');→ 结果为hello world - 注意:
std::erase是非成员函数,需包含<string></string>,不依赖迭代器范围 - 不兼容 C++17 及更早版本;若编译报错
no matching function for call to 'erase',说明标准未达标
用 erase + remove 组合(C++11 起通用)
这是最广泛兼容的写法,适用于所有支持 C++11 的环境。本质是“移除并擦除”两步:先用 std::remove 把所有 '\"' 挪到末尾,再用 string::erase 删掉那段区间。
容易踩的坑是只写 std::remove(s.begin(), s.end(), '"') 却忘了接 erase,导致字符串长度不变、末尾残留脏数据。
std::string s = "\"a\"\"b\"";s.erase(std::remove(s.begin(), s.end(), '"'), s.end());- 必须用
s.end()作第二参数,不能写s.begin()或硬编码位置 - 性能上无额外分配,就地完成,适合大字符串
用 std::regex_replace 替换(慎用)
虽然能写成 std::regex_replace(s, std::regex("\""), ""),但完全不推荐用于纯字符删除场景。
正则引擎启动开销大,编译正则模式有隐式成本,且对单字符匹配属于严重杀鸡用牛刀。实测在千次调用下比 erase+remove 慢 5–10 倍以上。
- 仅当逻辑扩展为“删双引号及其周围空格”或“按引号配对删内容”时才考虑 regex
- 若误把
"当作正则元字符处理,可能引发std::regex_error异常(实际不会,因为"在基本正则中无特殊含义,但易误导) - 需要额外包含
<regex></regex>,部分嵌入式 STL 实现甚至不提供该组件
手动循环 + erase(不推荐)
用 for 遍历并调用 string::erase(i, 1) 看似直观,但会触发多次内存搬移,时间复杂度 O(n²),且极易因索引越界或跳过字符出错。
典型翻车点:正向遍历时每删一个字符,后续字符前移,但循环变量仍自增,导致相邻双引号只删掉第一个。
- 反例:
for (size_t i = 0; i → 崩溃或漏删 - 若坚持手写,必须倒序遍历:
for (int i = s.size()-1; i >= 0; --i),但依然低效 - 除非调试极特殊边界(如需记录每个被删位置),否则毫无必要
真正要注意的是字符串是否含转义双引号——比如 "\"quoted\"" 中的 \" 是字面量反斜杠加双引号,不是真正的双引号字符。上述所有方法都只删裸 ",不会识别转义序列。如果需求是“按 C 字符串规则解析后删引号”,那就得先做转义解析,那是另一个问题了。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











