You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用std::accumulate拼接Boost::xpressive regex_search匹配结果

嘿,我懂你想摆脱普通for循环,用更函数式的方式来拼接Boost xpressive匹配到的子捕获组——其实std::accumulate完全能搞定,只是之前可能没找对正确的写法~下面就给你详细拆解两种场景的实现方式:

用std::accumulate拼接子匹配结果

首先要明确:smatch里的what[0]是整个正则匹配的内容,what[1]到what[n]才是你要的子捕获组,所以我们的遍历范围是what.begin()+1到what.end()。

1. 无分隔符的直接拼接

这种情况最简单,直接用空字符串作为初始值,通过lambda把每个子匹配的字符串追加到累计结果里:

std::string result = std::accumulate(
    what.begin() + 1, what.end(),
    std::string{},  // 初始值必须是std::string类型,别传const char*的""
    [](const std::string& acc, const boost::xpressive::ssub_match& sub) {
        return acc + sub.str();
    }
);

2. 带分隔符的拼接(比如添加"-")

直接用accumulate会导致开头/结尾多一个分隔符,这里给你两种优雅的解决方法:

方法一:先拿第一个子串当初始值,再拼接剩余部分

先判断是否存在子捕获组,然后把第一个子串作为初始值,从第二个子串开始累加,每次先加分隔符再加子串:

if (what.size() <= 1) {
    return "";  // 没有子捕获组的边界情况
}
std::string result = std::accumulate(
    what.begin() + 2, what.end(),
    what[1].str(),  // 用第一个子串当初始值
    [](const std::string& acc, const boost::xpressive::ssub_match& sub) {
        return acc + "-" + sub.str();
    }
);

方法二:用带状态的lambda处理首尾

如果不想单独处理第一个元素,可以捕获一个布尔变量标记是否是第一次拼接:

bool is_first = true;
std::string result = std::accumulate(
    what.begin() + 1, what.end(),
    std::string{},
    [&is_first](std::string acc, const boost::xpressive::ssub_match& sub) {
        if (is_first) {
            is_first = false;
            acc = sub.str();
        } else {
            acc += "-" + sub.str();
        }
        return acc;
    }
);

完整整合到你的foo函数

把上面的逻辑套进你的代码里,示例如下:

#include <string>
#include <numeric>
#include <boost/xpressive/xpressive.hpp>

std::string foo(const std::string& text) {
    using namespace boost::xpressive;
    sregex srx = +_d >> as_xpr("_") >> +_d; // 匹配类似"123_456"的数字组格式
    smatch what;
    if (regex_search(text, what, srx)) {
        // 这里用带分隔符的方法一示例
        if (what.size() <= 1) {
            return {};
        }
        return std::accumulate(
            what.begin() + 2, what.end(),
            what[1].str(),
            [](const std::string& acc, const ssub_match& sub) {
                return acc + "-" + sub.str();
            }
        );
    }
    return std::string();
}

比如输入"123_456",会返回"123-456";如果换成无分隔符的代码,会返回"123456"。

为什么之前用std::accumulate失败?

大概率是初始值类型不对——如果你传的是""(const char*类型),accumulate会默认把结果当成const char*处理,拼接时就会出错。一定要明确初始值是std::string{}或者what[1].str()这类std::string类型。

内容的提问来源于stack exchange,提问作者Eugene Mart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:58:15