c++20 中可用 std::erase(s, '~') 一步删除字符串中所有 ascii 波浪线;老标准需用 erase-remove 惯用法:s.erase(std::remove(s.begin(), s.end(), '~'), s.end());注意全角波浪线(u+301c 等)需额外处理。

用 std::erase 删除所有 '~' 字符(C++20)
如果你的编译器支持 C++20,std::erase 是最直接的方式:它原地修改字符串,语义清晰且无需手动管理迭代器。
常见错误是误用 std::remove 单独调用——它只移动元素、不缩容,必须配对 erase 才真正删除。而 std::erase 一步到位。
-
std::string s = "a~b~c~"; std::erase(s, '~');→s变成"abc" - 仅适用于容器支持擦除的字符类型,
std::string完全支持 - 注意:GCC 11+、Clang 12+、MSVC 19.30+ 才默认启用;若编译失败,检查是否开了
-std=c++20
兼容 C++11 的写法:erase-remove 惯用法
在老标准下,必须组合 std::remove 和 std::string::erase。漏掉 erase 是高频 bug,会导致“看似没删干净”——其实波浪线被移到末尾,但长度没变。
典型错误现象:"abc~~~" 经 std::remove 后变成 "abc~~~"(内容未变),因为没调 erase。
- 正确写法:
std::string s = "x~y~z~"; s.erase(std::remove(s.begin(), s.end(), '~'), s.end());
-
std::remove返回新逻辑结尾的迭代器,erase从该位置删到末尾 - 性能上,这是单次遍历 + 一次内存搬移,比循环
find + erase高效得多
需要保留其他符号?别误删 Unicode 波浪线
ASCII '~'(U+007E)和全角波浪线 ~(U+301C)、Unicode 浪线符号(如 U+FF5E)是不同字符。普通 erase 或 remove 只处理前者。
如果输入可能含中文环境下的波浪线,直接比较 '~' 会漏掉。
- 确认数据来源:日文输入法、某些编辑器粘贴常引入
~ - 若需统一处理,得用宽字符或 UTF-8 解码后比对码点,例如用
std::u32string+std::erase判断U'~'和U'~' - 简单场景下,可预处理:先用
std::replace把常见变体映射为 ASCII'~',再走标准流程
性能敏感时避免多次构造临时字符串
别写 s = std::regex_replace(s, std::regex("~"), "");——正则开销大,且生成新字符串,旧对象还得销毁。除非你要同时删多种模式,否则纯属杀鸡用牛刀。
也别用 for 循环配合 s.erase(i, 1):每次 erase 都触发内存搬移,O(n²) 时间复杂度。
- 坚持用
erase-remove或 C++20std::erase,都是 O(n) - 如果字符串超长(MB 级)且只删少量字符,考虑用双指针原地覆盖再截断,但绝大多数情况没必要
- 注意:
std::string的小字符串优化(SSO)会让短字符串操作极快,不用过早优化
~,查半天发现是前端传来的 UTF-8 全角符号。动手前先 printf("%02x ", (unsigned char)c) 看一眼原始字节,比猜强得多。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











