You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用非捕获组通过std::regex_replace替换标记间的空格?

问题分析与解决方案

我来帮你拆解下问题——你其实误解了非捕获组的作用,真正的问题出在正则匹配的范围上。

为什么会得到不符合预期的结果?

你的正则表达式(?:>)\s+(?:<)|\s+$中,(?:>)\s+(?:<)匹配的是完整的>\s+<序列(包括>、中间的空白和<)。std::regex_replace会把整个匹配到的内容全部替换成(newcontent),这就是为什么abc> <def会变成abc(newcontent)def——因为> <整个被替换掉了。

非捕获组(?:...)的作用只是告诉正则引擎“不要把这个组的内容保存到捕获组里”,它并不会改变“整个匹配内容被替换”的规则,所以你添加的std::regex::nosubs等参数也解决不了问题。

正确的解决方案:使用正向环视断言

要实现“只替换><之间的空白,保留><本身”的需求,你需要用正向环视断言来精准匹配中间的空白部分,而不包含前后的符号:

  • (?<=>):正向肯定后顾,确保当前位置的前面是>
  • (?=<):正向肯定预查,确保当前位置的后面是<

修正后的代码如下:

std::string in = "abc> <def\n" "xyz> \n";
std::regex re = R"(?<=>)\s+(?=<)|\s+$)";
std::string out = std::regex_replace(in, re, "(newcontent)");

运行这段代码后,out的值就会是你期望的:abc>(newcontent)<def xyz>(newcontent)

补充说明

你尝试的std::regex::ECMAScript | std::regex::nosubsstd::regex_constants::format_default参数,本质上和当前问题无关——前者是控制正则的语法规则和捕获组行为,后者是指定替换格式,它们都无法改变正则匹配的范围,所以对你的问题没有帮助。

内容的提问来源于stack exchange,提问作者Bo R

火山引擎 最新活动