C++ 正则实现字符串标点前后空格格式化的问题咨询
现有方案运行原理
你提供的代码核心是通过正则匹配替换实现标点前空格的清理,逻辑拆解如下:
- 正则
\s+(?=[\.,])使用了正向肯定预查规则:\s+匹配连续1个及以上的空白字符(?=[\.,])属于零宽断言,仅校验匹配到的空白后面是否紧接.或,,不会消耗标点字符本身
- 后续调用
std::regex_replace将匹配到的所有标点前空白替换为空字符串,就实现了第一部分需求 - 注意原代码存在语法隐患:C++普通字符串中
\为转义符,直接写"\s+"会被识别为非法转义,需要改为原始字符串字面量R"(\s+(?=[\.,]))",或者转义为"\\s+(?=[\\.,])"才能正常运行。
第二部分需求适配方案
你可以新增一轮正则替换,实现标点后无空格时的自动补全逻辑,最终代码如下:
#include <string> #include <regex> #include <iterator> std::string fix_string(const std::string& str) { // 第一步:清理标点前的空格 static const std::regex rgx_remove_space_before_punc(R"(\s+(?=[\.,]))"); std::string temp; temp.reserve(str.size() + 10); // 预留补空格的空间 std::regex_replace(std::back_inserter(temp), str.cbegin(), str.cend(), rgx_remove_space_before_punc, ""); // 第二步:标点后无空格时补空格,匹配标点后紧跟非空白字符的场景 static const std::regex rgx_add_space_after_punc(R"(([\.,])(?=[^\s]))"); std::string rtn; rtn.reserve(temp.size()); std::regex_replace(std::back_inserter(rtn), temp.cbegin(), temp.cend(), rgx_add_space_after_punc, "$1 "); return rtn; }
新增逻辑说明
新增的正则([\.,])(?=[^\s])同样用了正向预查:
([\.,])捕获匹配到的.或,,替换时用$1引用保留原标点(?=[^\s])仅当标点后面紧跟非空白字符时触发匹配,标点后已经有空格、或者标点在句子末尾的场景不会触发替换,刚好符合你的需求。
用你提供的输入示例测试:
输入:I would ,if at all possible , like to write this sentence properly .
第一步处理后得到:I would,if at all possible, like to write this sentence properly.
第二步处理后得到你需要的期望输出:I would, if at all possible, like to write this sentence properly.
内容的提问来源于stack exchange,提问作者Jo Schmo
相关产品推荐
相关产品推荐

