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
相关产品推荐
相关产品推荐

