c++oding="utf-8" ?>
std::regex_replace是最直白的临时解决方案,一行即可替换连续空格,但默认仅处理ascii空格;用"s+"可匹配所有空白字符,但会误删首尾空格。

用 std::regex_replace 最快写出来
如果你只是临时处理、不追求极致性能,std::regex_replace 是最直白的选择。它能一行搞定连续空格替换,但要注意默认正则引擎在某些标准库(如 libstdc++)里可能较慢或不完全符合预期。
-
std::regex_replace(s, std::regex(" +"), " ")只能处理 ASCII 空格,对、无效 - 想匹配所有空白字符(包括制表符、换行等),改用
std::regex("\s+"),但需注意:它会把开头/结尾的空白也“压缩”进结果,可能意外删掉首尾空格 - 若要保留首尾空格,只压缩中间连续部分,得组合使用
std::regex("(? —— 但这个断言在 MSVC 和 libstdc++ 上支持度不一,建议先测试
手写双指针遍历更可控
多数真实项目里,你真正需要的是稳定、可预测、无正则开销的行为。双指针法自己控制逻辑,兼容性好,还能顺便处理首尾空格策略。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 用两个索引:
read扫描原字符串,write写入目标位置 - 遇到非空格字符,直接复制;遇到空格时,只在
write为 0 或前一个字符不是空格时才写入一个空格 - 这样天然跳过所有连续空格,且不碰首尾 —— 比如
" hello world "→" hello world " - 最后用
s.resize(write)截断多余字符;如果原字符串不允许修改,就新建std::string并返回
std::unique 配合 lambda 不适合这个任务
有人试过用 std::unique 去重相邻空格,但这是典型误用。
-
std::unique只能删除「相邻且相等」的元素,而它判断相等是基于值(' '==' '),所以确实能删掉连续空格 - 但它无法区分「空格」和「其他字符」,比如
"a b"会被变成"a b"(正确),但"a b c"会变成"a b c"(看起来没变,其实内部调用多次比较,效率低) - 更大的问题是:它不能跳过非空格字符做条件判断,也没法单独对空格做压缩 —— 它只是通用去重,语义上不匹配需求
- 而且
std::unique返回的是新逻辑终点迭代器,必须手动erase,容易漏写,反而增加出错概率
注意 locale 和 Unicode 边界情况
上面所有方法都假设输入是纯 ASCII 字符串。一旦涉及 UTF-8 编码的中文、日文或带重音符号的西文字母,事情就变了。
-
std::regex("\s+")在宽字符模式下(std::wregex)行为更可靠,但你要先把 UTF-8 转成std::wstring,这本身就有编码转换成本 - 双指针法在 UTF-8 下不能直接按
char操作 —— 一个汉字占 3 字节,简单跳过' '没问题,但若想识别 Unicode 空格(如 、 ),就得用 ICU 或std::codecvt_utf8(已弃用)这类方案 - 实际项目中,除非明确要求支持全 Unicode 空格类字符(U+2000–U+200F、U+3000 等),否则默认按 ASCII 空格处理即可,避免过早引入复杂依赖
真正麻烦的不是怎么写,而是决定“空格”的定义范围 —— 是仅 ASCII ' ',还是含
,还是所有 Unicode 分隔符。这个边界没划清,代码写得再漂亮也容易返工。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










