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

C++正则表达式匹配string_view:如何通过引用获取结果避免堆拷贝?

C++正则匹配避免中间拷贝获取子匹配方案

关于正则内部实现的疑问

你的猜测是对的:C++标准库的正则实现内部确实依赖原始缓冲区的迭代器/指针,不会主动为子匹配创建新的堆内存拷贝——除非你显式调用operator string_type()或者str()方法触发转换。

C++17中的解决方案

在C++17里,std::sub_match本身是一个迭代器对(继承自std::pair<BidirIt, BidirIt>),你可以直接访问它的first和second成员,这两个就是指向原始缓冲区的迭代器,完全不需要拷贝:

#include <regex>
#include <string>
#include <iostream>
#include <string_view>

int main() {
    const std::string buf = "Hello 123 World 456";
    std::regex re(R"(\d+)");
    
    std::smatch match;
    auto it = buf.cbegin();
    while (std::regex_search(it, buf.cend(), match, re)) {
        // 直接通过迭代器范围访问原始数据,无拷贝
        std::cout << "匹配内容:";
        std::cout.write(&*match[0].first, match[0].length()) << '\n';
        
        // 构造C++17的string_view视图,同样无拷贝
        std::string_view view(match[0].first, match[0].length());
        std::cout << "string_view视图:" << view << '\n';
        
        it = match[0].second; // 移动迭代器到当前匹配的末尾,继续下一轮搜索
    }
    return 0;
}

你提到的position(i)和length(i)也是可行方案,结合原始字符串的地址就能构造无拷贝的视图:

// 用position和length构造string_view
std::string_view view(&buf[match.position(0)], match.length(0));

C++20的优化

升级到C++20后,std::sub_match新增了operator std::basic_string_view()的隐式转换,写法更简洁,同样没有拷贝:

std::string_view view = match[0]; // C++20起直接支持

同时C++20的正则相关接口对迭代器范围的处理做了进一步优化,能更高效地避免不必要的内存操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:54:55