c++20中推荐用std::erase(s, '"')和std::erase(s, '\'')分别删除双引号和单引号;c++11起可用erase-remove惯用法:s.erase(remove_if(s.begin(), s.end(), [](char c){return c=='\"'||c=='\'';}), s.end())。

用 std::erase 删除所有单双引号(C++20)
如果你的编译器支持 C++20,std::erase 是最直接的方式:它原地修改字符串,自动处理迭代器失效问题,且语义清晰。
注意:std::erase 是容器擦除的统一接口,对 std::string 有效,但不改变原有引用/指针有效性(因为只是内部数据重排,不是 realloc)。
std::string s = "He said: \"Hello\" and 'world'"; std::erase(s, '"'); std::erase(s, '\''); // s 变成 "He said: Hello and world"
- 两次调用分别删双引号和单引号;顺序无关
- 不能写成
std::erase(s, '"', '\'')—— 这个重载不存在,会编译失败 - 如果字符串很大、引号极少,性能略逊于手写循环(因需遍历两次),但通常可忽略
用 std::remove_if + erase(C++11 起通用)
这是兼容性最好的方案,适用于所有支持 C++11 的环境。核心是「移除-擦除惯用法(erase–remove idiom)」:先逻辑移动非目标字符到前端,再一次性截断尾部。
常见错误是只调用 std::remove_if 却忘记后续 erase,结果字符串长度不变,只是末尾残留脏数据。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
std::string s = "It's \"tricky\".";
s.erase(
std::remove_if(s.begin(), s.end(), [](char c) {
return c == '"' || c == '\'';
}),
s.end()
);
- lambda 中必须用
c == '"' || c == '\'',不能写成c == "\""(字符串字面量)或漏掉转义 - 单引号在 char 字面量中写成
'\'',这是唯一合法写法;写'''会编译报错 - 该方式只遍历一次,比两次
std::erase略快,尤其对长字符串
手动循环 + erase(易出错,慎用)
新手常写的 for 循环直接调用 string::erase,但极易因迭代器失效导致越界或跳过字符。
典型错误写法:for (int i = 0; i —— 删除后后面字符前移,但 <code>i 仍自增,导致下一个字符被跳过。
- 若坚持手动遍历,必须倒序:
for (int i = s.size()-1; i >= 0; --i) - 或者用迭代器并接收
erase返回值:it = s.erase(it),删除后it已指向下一位置 - 除非有特殊需求(如需记录删除位置),否则没必要手写——既难读又易错
处理原始字符串字面量或 JSON 场景的额外提醒
如果你实际是在解析 JSON 或处理带转义的字符串(比如 "He said: \"Hi\""),要注意:这里的反斜杠+引号是转义序列,属于一个逻辑字符,但存储为两个字节。上面所有方法都按字节操作,会把 \ 和 " 当作独立字符处理,可能误删反斜杠。
- 上述方案只适合「纯清洗」场景(如预处理用户输入、日志字段清理)
- 若需保留转义语义(例如只删未转义的引号),必须先做转义解析,不能直接用
remove_if - 正则(
std::regex_replace)看似方便,但启动开销大、不可控、且对空字符敏感,不推荐用于简单字符剔除
std::erase 或 remove_if;含转义就得先解码再删,否则删掉的是语法结构的一部分。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










