C++ 正则表达式分组捕获入门指南

news2025/2/26 14:04:12

在 C++ 中,正则表达式(regex)是一种用于匹配字符串模式的强大工具。正则表达式不仅能帮助你查找符合特定模式的字符,还能捕获匹配的子字符串(即分组捕获)。这篇文章将介绍 C++ 正则表达式中的分组捕获机制,并提供多个示例代码来帮助你快速入门。

一、基本概念:正则表达式分组捕获

正则表达式分组捕获是一种能够将匹配的部分提取出来的技术。在 C++ 中,正则表达式分组捕获通常通过小括号 () 来实现。每个分组会捕获匹配到的子字符串,并且可以在代码中通过相应的索引访问它们。

分组的基本语法
  • ():用于定义捕获分组。你可以在正则表达式中使用多个分组,C++ 中从 1 开始对分组编号。
示例:简单分组捕获

假设我们需要从一个日期字符串中提取年月日,可以使用正则表达式中的分组捕获来实现。

二、C++ 正则表达式库:<regex>

在 C++ 中使用正则表达式时,需要包含头文件 <regex>。基本的正则表达式操作包括:

  • std::regex:正则表达式对象。
  • std::smatch:保存匹配结果的对象。
  • std::regex_search:查找匹配。
  • std::regex_match:完全匹配整个字符串。
  • std::regex_replace:替换匹配的字符串。

三、示例代码:日期分组捕获

我们可以编写一个示例程序,从一个字符串中提取出日期的年、月和日。

示例 1:提取日期(YYYY-MM-DD

假设我们有一个日期字符串 2023-02-25,并希望通过正则表达式捕获出年、月、日。

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

int main() {
    std::string input = "2023-02-25";
    
    // 正则表达式:捕获年、月和日
    std::regex pattern(R"((\d{4})-(\d{2})-(\d{2}))");
    std::smatch matches;

    // 如果匹配成功
    if (std::regex_match(input, matches, pattern)) {
        // 输出捕获的各个分组
        std::cout << "Year: " << matches[1] << std::endl;
        std::cout << "Month: " << matches[2] << std::endl;
        std::cout << "Day: " << matches[3] << std::endl;
    } else {
        std::cout << "No match found." << std::endl;
    }

    return 0;
}
代码解析:
  1. 正则表达式

    R"((\d{4})-(\d{2})-(\d{2}))"
    

    • (\d{4}) 捕获4位数字(即年份)。
    • (\d{2}) 捕获2位数字(即月份和日期)。
  2. matches[1]matches[2]matches[3] 分别存储匹配到的年份、月份和日期。

输出:
Year: 2023
Month: 02
Day: 25

四、捕获多个匹配

有时我们需要从文本中查找多个匹配项。std::regex_search 可以用于查找匹配,但它只会找到第一个匹配项。如果你想捕获所有匹配项,可以使用 std::regex_iterator

示例 2:提取所有匹配的日期

假设我们有一段文本,其中包含多个日期,我们希望提取所有日期。

#include <iostream>
#include <regex>
#include <string>
#include <iterator>

int main() {
    std::string input = "The event will be held on 2023-02-25, followed by another on 2024-03-01.";
    
    // 正则表达式:捕获日期
    std::regex pattern(R"((\d{4})-(\d{2})-(\d{2}))");
    std::smatch matches;

    // 使用 regex_iterator 查找所有匹配
    auto begin = std::sregex_iterator(input.begin(), input.end(), pattern);
    auto end = std::sregex_iterator();

    for (auto it = begin; it != end; ++it) {
        std::cout << "Found date: " << it->str() << std::endl;
    }

    return 0;
}
输出:
Found date: 2023-02-25
Found date: 2024-03-01
使用 std::regex_search 来查找日期的所有匹配
#include <iostream>
#include <regex>
#include <string>

int main() {
    std::string input = "The event will be held on 2023-02-25, followed by another on 2024-03-01.";

    // 正则表达式:捕获日期
    std::regex pattern(R"((\d{4})-(\d{2})-(\d{2}))");
    std::smatch matches;

    // 使用 cbegin 和 cend 来获取常量迭代器
    auto begin = input.cbegin();

    while (std::regex_search(begin, input.cend(), matches, pattern)) {
        // 输出匹配到的日期
        std::cout << "Found date: " << matches[0] << std::endl;

        // 更新搜索起始位置,继续从上一个匹配位置之后开始搜索
        begin = matches[0].second;
    }

    return 0;
}

输出:
Found date: 2023-02-25
Found date: 2024-03-01

五、捕获和替换(regex_replace

正则表达式不仅可以用于查找和捕获,还可以用于替换匹配的内容。通过 std::regex_replace,你可以将捕获到的内容替换成新的内容。

示例 3:替换日期格式

假设我们希望将日期格式从 YYYY-MM-DD 更改为 DD/MM/YYYY

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

int main() {
    std::string input = "The event will be held on 2023-02-25, and another on 2024-03-01.";
    
    // 正则表达式:捕获日期
    std::regex pattern(R"((\d{4})-(\d{2})-(\d{2}))");
    
    // 使用 regex_replace 将日期格式替换为 DD/MM/YYYY
    std::string output = std::regex_replace(input, pattern, R"($3/$2/$1)");
    
    std::cout << "Updated text: " << output << std::endl;

    return 0;
}
输出:
Updated text: The event will be held on 25/02/2023, and another on 01/03/2024.

六、进阶应用:捕获多个分组

当正则表达式中有多个分组时,你可以通过 matches[n] 访问每个分组的捕获结果。

示例 4:捕获多个分组(例如,提取姓名和年龄)
#include <iostream>
#include <regex>
#include <string>

int main() {
    std::string input = "John Doe, Age: 30; Jane Smith, Age: 25";
    
    // 正则表达式:捕获姓名和年龄
    std::regex pattern(R"((\w+ \w+), Age: (\d+))");
    std::smatch matches;

    // 查找匹配
    auto begin = std::sregex_iterator(input.begin(), input.end(), pattern);
    auto end = std::sregex_iterator();

    for (auto it = begin; it != end; ++it) {
        std::cout << "Name: " << it->str(1) << ", Age: " << it->str(2) << std::endl;
    }

    return 0;
}
输出:
Name: John Doe, Age: 30
Name: Jane Smith, Age: 25

七、总结

正则表达式的分组捕获是一个非常强大的工具,它能够让你轻松提取和操作字符串中的特定部分。C++ 中的 <regex> 库提供了灵活的接口,允许你使用正则表达式进行模式匹配、捕获分组、查找多个匹配项以及进行替换操作。通过本文的示例代码,希望你能掌握 C++ 中正则表达式分组捕获的基础应用,并能在实际项目中灵活使用正则表达式来处理文本数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2306395.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#中级教程(1)——解锁 C# 编程的调试与错误处理秘籍

一、认识错误&#xff1a;编程路上的 “绊脚石” 在 C# 编程中&#xff0c;错误大致可分为两类&#xff1a;语法错误和语义错误&#xff08;逻辑错误&#xff09;。语法错误就像是写作文时的错别字和病句&#xff0c;编译器一眼就能识别出来&#xff0c;比如变量名拼写错误、符…

Jmeter接口并发测试

Apache JMeter 是一款开源的性能测试工具&#xff0c;广泛用于接口并发测试、负载测试和压力测试。以下是使用 JMeter 进行接口并发测试的详细步骤&#xff1a; 一、准备工作 安装 JMeter 下载地址&#xff1a;Apache JMeter 官网 确保已安装 Java 环境&#xff08;JMeter 依…

MySQL-增删改查

一、Create(创建) &#x1f4d6; 语法&#xff1a; INSERT INTO table_name(value_list); 当我们使用表的时候&#xff0c;就可以使用这个语法来向表中插入元素~ 我们这边创建一个用于示范的表(Student)~ create table student( id int, name varchar(20), chinese int, math…

开源堡垒机 JumpServer 社区版实战教程:发布机的配置与Website资产配置使用

文章目录 开源堡垒机 JumpServer 社区版实战教程&#xff1a;发布机的配置与Website资产配置使用一、功能简述二、应用发布机2.1 版本要求2.2 创建应用发布机2.2.1 通过WinRM的协议进行应用发布机的创建2.2.2 通过OpenSSH的协议进行应用发布机的创建2.2.2.1 下载OpenSSH2.2.2.2…

代码随想录算法训练day64---图论系列8《拓扑排序dijkstra(朴素版)》

代码随想录算法训练 —day64 文章目录 代码随想录算法训练前言一、53. 117. 软件构建—拓扑排序二、47. 参加科学大会---dijkstra&#xff08;朴素版&#xff09;总结 前言 今天是算法营的第64天&#xff0c;希望自己能够坚持下来&#xff01; 今天继续图论part&#xff01;今…

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷(四)

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷&#xff08;四&#xff09; 第一部分&#xff1a;网络平台搭建与设备安全防护任务书第二部分&#xff1a;网络安全事件响应、数字取证调查、应用程序安全任务书任务 1&#xff1a;应急响应&…

单片机的串口(USART)

Tx - 数据的发送引脚&#xff0c;Rx - 数据的接受引脚。 串口的数据帧格式 空闲状态高电平&#xff0c;起始位低电平&#xff0c;数据位有8位校验位&#xff0c;9位校验位&#xff0c;停止位是高电平保持一位或者半位&#xff0c;又或者两位的状态。 8位无校验位传输一个字节…

动态规划(背包问题)--是否逆序使用的问题--二进制拆分的问题

动态规划&#xff08;背包问题&#xff09; 题目链接01背包代码 完全背包问题代码 多重背包问题 I代码 什么时候适用逆序多重背包问题 II&#xff08;超百万级的复杂度&#xff09;代码 关于二进制拆分 题目链接 01背包 代码 #include <iostream> #include <vector&…

Mac 版 本地部署deepseek ➕ RAGflow 知识库搭建流程分享(附问题解决方法)

安装&#xff1a; 1、首先按照此视频的流程一步一步进行安装&#xff1a;(macos版&#xff09;ragflowdeepseek 私域知识库搭建流程分享_哔哩哔哩_bilibili 2、RAGflow 官网文档指南&#xff1a;https://ragflow.io 3、RAGflow 下载地址&#xff1a;https://github.com/infi…

姿态矩阵/旋转矩阵/反对称阵

物理意义&#xff0c;端点矢量角速率叉乘本身向量&#xff1b; 负号是动系b看固定系i是相反的&#xff1b; 一个固定 在惯性导航解算中&#xff0c;旋转矢量的叉乘用于描述姿态矩阵的微分方程。你提到的公式中&#xff0c; ω i b b \boldsymbol{\omega}_{ib}^b \times ωibb…

【大语言模型】【整合版】DeepSeek 模型提示词学习笔记(散装的可以看我之前的学习笔记,这里只是归纳与总结了一下思路,内容和之前发的差不多)

以下是个人笔记的正文内容: 原文在FlowUs知识库上&#xff0c;如下截图。里面内容和这里一样&#xff0c;知识排版好看一点 一、什么是 DeepSeek 1. DeepSeek 简介 DeepSeek 是一家专注于通用人工智能&#xff08;AGI&#xff09;的中国科技公司&#xff0c;主攻大模型研发与…

ollama无法通过IP:11434访问

目录 1.介绍 2.直接在ollama的当前命令窗口中修改&#xff08;法1&#xff09; 3.更改ollama配置文件&#xff08;法2&#xff09; 3.1更新配置 3.2重启服务 1.介绍 ollama下载后默认情况下都是直接在本地的11434端口中运行&#xff0c;绑定到127.0.0.1(localhost)&#x…

Bugku CTF CRYPTO

Bugku CTF CRYPTO 文章目录 Bugku CTF CRYPTO聪明的小羊ok[-<>]散乱的密文.!? 聪明的小羊 描 述: 一只小羊翻过了2个栅栏 fa{fe13f590lg6d46d0d0} 分 析&#xff1a;栅栏密码&#xff0c;分2栏&#xff0c;一个栏里有11个 ①手动解密 f a { f e 1 3 f 5 9 0 l g 6 d 4 …

【洛谷】【ARC100E】Or Plus Max(高维前缀和)

传送门&#xff1a;Or Plus Max 高维前缀和 题目描述 長さ 2N の整数列 A0​, A1​, ..., A2N−1​ があります。&#xff08;添字が 0 から始まることに注意&#xff09; 1 ≤ K ≤ 2N−1 を満たすすべての整数 K について、次の問題を解いてください。 i,j を整数と…

SmolLM2:多阶段训练策略优化和高质量数据集,小型语言模型同样可以实现卓越的性能表现

SmolLM2 采用创新的四阶段训练策略&#xff0c;在仅使用 1.7B 参数的情况下&#xff0c;成功挑战了大型语言模型的性能边界&#xff1a; 在 MMLU-Pro 等测试中超越 Qwen2.5-1.5B 近 6 个百分点数学推理能力&#xff08;GSM8K、MATH&#xff09;优于 Llama3.2-1B在代码生成和文…

《Effective Objective-C》阅读笔记(中)

目录 接口与API设计 用前缀避免命名空间冲突 提供“全能初始化方法” 实现description方法 尽量使用不可变对象 使用清晰而协调的命名方式 方法命名 ​编辑类与协议命名 为私有方法名加前缀 理解OC错误模型 理解NSCopying协议 协议与分类 通过委托与数据源协议进行…

Hbase客户端API——语句大全

目录 创建表&#xff1a; 插入数据&#xff1a; 删除数据&#xff1a; 修改数据&#xff1a; 查询数据&#xff1a;Get 查询数据&#xff1a;Scan 查询数据&#xff1a;过滤查询 创建表&#xff1a; 检验&#xff1a; 插入数据&#xff1a; 验证 一次多条数据插入 验证&…

MQ(Message Queue)

目录 MQ(Message Queue)基本概念 为什么要使用消息队列&#xff1f; 使用消息队列有什么缺点&#xff1f; 如何保证消息不丢失?(如何保证消息的可靠性传输?/如何处理消息丢失的问题?) 通用的MQ场景&#xff1a; RabbitMQ如何保证消息不丢失&#xff1f; 生产者丢数据…

计算机网络————(三)

前文二 前文一 Websocket协议 是一种存在TCP协议之上的协议 当客户端需要了解服务器是否更新就需要不断给客户端发送请求询问是否更新&#xff0c;这行会造成服务端压力很大 而Websocket相当于服务器一旦更新了就会给客户端发送消息表明自己更新了&#xff0c;类似客户端订阅…

【音视频】音视频录制、播放原理

一、音视频录制原理 通常&#xff0c;音视频录制的步骤如下图所示&#xff1a; 我们分别从音频和视频开始采样&#xff0c;通过麦克风和摄像头来接受我们的音频信息和图像信息&#xff0c;这通常是同时进行的&#xff0c;不过&#xff0c;通常视频的采集会比音频的采集慢&…