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

news/2025/2/26 23:39:51

在 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.niftyadmin.cn/n/5869277.html

相关文章

一文2500字从0到1实现压测自动化!

大家好&#xff0c;我是小码哥&#xff0c;最近工作有点忙&#xff0c;一直在实现压测自动化的功能&#xff0c;今天来分享一下实现思路 我所在的业务线现在项目比较少了&#xff0c;所以最近一个月我都没有做业务测试&#xff0c;需求开发完后RD直接走免测就上线&#xff0c;…

腾讯SQL面试题变体实现:最长连续天数与允许1天中断的进阶解法

腾讯SQL面试题变体实现:最长连续天数与允许1天中断的进阶解法 作者:某七年数据开发工程师 | 2025年02月23日 关键词:滑动窗口、容错机制、连续区间优化 一、变体题型需求分析 在原题如何找出连续5天涨幅超过5%的股票基础上,需实现两个扩展场景: 最长连续天数:输出每只股…

物联网智能终端-低成本方案(HC32L196+EC800G+BLE+2.8寸串口屏)

背景介绍 公司前几年搞了一些基于Linux系统的网关和智能终端的开发工作&#xff0c;产品已经量产&#xff0c;投放市场后发现有几个问题&#xff0c;第一个问题是成本&#xff0c;能跑Linux系统的处理器成本都比较高&#xff0c;当然了它的性能也是比较强。第二个问题是功耗&am…

【Java项目】基于Spring Boot的旧物置换系统

【Java项目】基于Spring Boot的旧物置换系统 技术简介&#xff1a;采用Java技术、Spring Boot框架、MySQL数据库等实现。 系统简介&#xff1a;旧物置换系统包括管理员、用户、卖家。其主要功能包括管理员&#xff1a;首页、个人中心、用户管理、卖家管理、旧物类型管理、旧物信…

2 Text2SQL 智能报表方案介绍

0 背景 Text2SQL智能报表方案旨在通过自然语言处理&#xff08;NLP&#xff09;技术&#xff0c;使用户能够以自然语言的形式提出问题&#xff0c;并自动生成相应的SQL查询&#xff0c;从而获取所需的数据报表&#xff0c;用户可根据得到结果展示分析从而为结论提供支撑&#…

基于AI人工智能UI自动化测试工具:Midscene

前言 随着互联网技术的飞速发展&#xff0c;Web应用越来越普及&#xff0c;前端页面也越来越复杂。为了确保产品质量&#xff0c;UI自动化测试成为了开发过程中不可或缺的一环。然而&#xff0c;传统的UI自动化测试工具往往存在学习成本高、维护困难等问题。特别是UI 自动化脚…

QT各种版本下载安装

参考链接&#xff1a; 【Qt】超详细&#xff01;Qt4.8.6和VS2010的配置及使用 由于QT官网一般现在进不去&#xff0c;所以下载一些QT版本只能通过镜像或者以前下载存储的安装包来进行&#xff0c;现在推荐两种方法 从参考链接中搬过来&#xff1a; 方案一&#xff1a;国内镜…

Qt在Linux嵌入式开发过程中复杂界面滑动时卡顿掉帧问题分析及解决方案

Qt在Linux嵌入式设备开发过程中&#xff0c;由于配置较低&#xff0c;加上没有GPU&#xff0c;我们有时候会遇到有些组件比较多的复杂界面&#xff0c;在滑动时会出现掉帧或卡顿的问题。要讲明白这个问题还得从CPU和GPU的分工说起。 一、硬件层面核心问题根源剖析 CPU&#x…