当前位置: 首页 > news >正文

sub_match

1. 核心概念:它不是“字符串”,它是“书签”

这是理解 sub_match 最重要的一点:

  • 直觉误区:很多人以为 sub_match 里直接存了 "2023" 这样的字符串。
  • 实际情况sub_match 不存储字符串拷贝。它只存储了两个指针(迭代器),分别指向原字符串中匹配开始和结束的位置。

比喻: 如果原字符串是一本很厚的书,sub_match 并不是把某一页撕下来给你,而是夹了两个书签,告诉你:“这一段内容,从第 50 页第 3 行开始,到第 50 页第 8 行结束”。

优点:非常快,不占内存(不需要复制字符串)。 缺点:如果原书(原字符串)被烧了(被销毁了),这两个书签就失效了(悬空指针)。


2. 三大核心成员变量

当拿到一个 sub_match 对象(比如 matches[1])时,你主要使用这三个功能:

A. .str() —— “给我复印件”

这是最常用的方法。因为它只存了指针,如果你想要一个真正的 std::string 来处理,就调用这个。

C++

std::string s = match.str(); // 把指针指向的范围拷贝出来,变成字符串

B. .length() —— “有多长”

告诉你这段匹配的内容有多少个字符。

C. .matched —— “这个组抓到东西了吗?”

这是一个 bool 变量。 在正则表达式中,有些组是可选的(比如用了 ?*)。如果这个组在这次匹配中没出现,.matched 就是 false


3. 代码实战演示

我们用一个“解析日期”的例子来彻底看懂 sub_match 的内部结构。

#include <iostream>
#include <regex>
#include <string>int main() {std::string text = "Today is 2023-12-09.";// 正则:(\d{4}) -> 年, (\d{2}) -> 月, (\d{2}) -> 日// 注意:这里有 3 个括号,也就是 3 个 sub_matchstd::regex pattern(R"((\d{4})-(\d{2})-(\d{2}))");std::smatch results; // 这是一个数组,里面存的全是 sub_matchif (std::regex_search(text, results, pattern)) {// results[0] 是特殊的 sub_match,代表“整个匹配到的式子”std::cout << "完整匹配: " << results[0].str() << std::endl; // 输出: 2023-12-09// results[1] 是第 1 个括号 (年) 的 sub_matchstd::sub_match<std::string::const_iterator> year = results[1];std::cout << "年份: " << year.str() << std::endl; // 输出: 2023// results[2] 是第 2 个括号 (月)std::cout << "月份长度: " << results[2].length() << std::endl; // 输出: 2// 演示 .matched 属性// 假设我们要匹配可选的时间部分 (T\d+)? // 如果原句里没有时间,results[4].matched 就为 false}return 0;
}

4. 这里的“坑” (高手进阶)

因为 sub_match 只是指针(迭代器),所以它的生命周期必须依附于原字符串。

❌ 极度危险的代码(未定义行为):

std::sub_match<...> get_version() {std::string temp = "Version 1.0"; // 这是一个局部变量std::regex r(R"(Version (\d+))");std::smatch m;std::regex_search(temp, m, r);return m[1]; // 错误!!!// 函数结束时,temp 字符串被销毁了。// 返回的 sub_match 指向了一块已经被回收的内存。// 之后如果你调用 .str(),程序可能会崩溃。
}

✅ 正确做法: 如果你要把结果传出去,必须把它转换成 string

std::string get_version() {// ... 同上 ...return m[1].str(); // 正确:这就创建了一个独立的字符串拷贝
}

总结

  1. sub_match 是匹配结果的一个切片
  2. 它主要包含两个迭代器(开始和结束)和一个 bool 标志(是否匹配)。
  3. 最常用 .str() 把切片转成字符串。
  4. 切记:原字符串销毁后,sub_match 就不能用了。
http://www.jsqmd.com/news/115936/

相关文章:

  • 抽奖机随机号码生成:3 种算法实现 + 测试全解析(附完整代码)
  • 【零基础精通】Python 字符串全解析:从字符序列到不可变对象的深度构建
  • item14--谨慎考虑资源管理类的拷贝行为
  • python django flask酒店客房管理系统数据可视化分析系统_gq8885n3--论文md5
  • python django flask鹿幸公司员工食堂在线点餐餐饮餐桌预约管理系统的设计与实现_utcnqqs0--论文
  • error_code
  • 虚拟化初步了解
  • Miloco 深度打通 Home Assistant,实现设备级精准控制
  • 好用的大型牛场水滴粉碎机技术强的
  • set_value
  • 日记1217
  • function的类型擦除
  • function bind
  • 日记12,19
  • Item10--令赋值操作符返回一个
  • Item9--绝不在构造和析构过程中调用虚函数
  • python django flask考研互助交流平台_c62p51fu--论文
  • 日记12.18
  • 离散化遍历
  • Ubuntu上使用VScode创建Maven项目
  • 线程(2)
  • 大规模语言模型的抽象思维与创新能力培养
  • 线程(1)
  • 方达炬〖发明超新技术〗:冰堆技术;冷极冰堆建筑技术;
  • Item6--若不想使用编译器自动生成的函数,就该明确拒绝
  • 我发现LLM解析基因数据优化抗癌药剂量,患者副作用直降40%
  • 日记12.16
  • 论文AIGC查重率高怎么办?6个降AI率工具和技巧,AI率从100%降到3%! - 还在做实验的师兄
  • PCL曲面重建——为一组点云重建凸多边形/凹多边形
  • 信息与关系:涌现的三大核心原则