转自个人博客

1. 概述

1.1 正则表达式概述

正则表达式(Regular Expressions,简称 regex)是用于匹配文本模式的一种特殊字符序列,其可以用一系列字符来表示出不同文本的对应模式。正则表达式的应用范围十分广泛,包括验证文本格式、判断字符种类、解析文本信息、转换目标文本、遍历搜索文本、符号化文本等。

一般在文件搜索、浏览器搜索时都可以使用正则表达式来表达某一种想要的文本格式,在C++等编程语言中也是一样,灵活正当地使用正则表达式可以很有效地提高代码的可读性和简洁性。

另外要注意的是,随着时间的推移,正则表达式的语法也在扩充升级,而C++对以下几种语法均有着很好的支持,其中最主要的掌握ECMAScript就好:

  • ECMAScript:基于ECMAScript标准的语法。JavaScript、ActionScript和Jscript等语言都使用该标准。
  • basic:基本的POSIX语法。
  • extended:拓展的POSIX语法。
  • awk:POSIX awk实用工具使用的语法。
  • grep:POSIX grep实用工具使用的语法。
  • egrep:用逗号分隔的POSIX egrep语法。

1.2 C++中使用正则表达式

在 C++11 之前,C++ 并未内置正则表达式库,不能直接使用正则表达式。如果开发者想要使用正则表达式对文本作快捷操作,那么就需要依赖第三方库如 PCRE (Perl Compatible Regular Expressions) 或使用 Boost库中的 Boost.Regex。而在 C++11 中,C++ 标准库引入了<regex> 头文件,这样在C++中使用正则表达式就不需要链接导入第三方库了。

示例:

#include <iostream>
#include <regex>
using namespace std;int main(){string text = "The number is 42";regex number_pattern("\\d+"); // 建立匹配模式,查找字符串中是否有数字if(regex_search(text, number_pattern)){cout << "Found a number!" << endl;}
}

2. 正则表达式的语法规则

正则表达式会用到的特殊字符为:^ $ \ . * + ? () [] {} |

每个字符的含义和用处将在下面逐步介绍。

2.1 单字符匹配

除了正则表达式会用到的特殊字符外,单个字符(包括大小写字母、数字、其他字符等)就匹配指定的字符,比如:a 匹配字符 a

如果要匹配特殊字符,则需要使用特殊字符中的转义字符\,比如:\^ 匹配字符 ^

对于需要匹配的文本中有未指定字符,就可以使用通配符.(点,英文句号)。通配符可以匹配任意单个字符,一般用在有部分不确定字符的情况下,比如a.c可以匹配到abca1c等一系列文本。只使用单个通配符就表示只匹配总长度为1的文本。

如果指定匹配任意数字或任意字母等非全部的情况时,可以使用字符类来指定一个范围的字符,见下一小节。

2.2 字符类

  1. 预定义字符类

    是正则表达式内定的用于表示一类字符的情况,用于匹配单一字符

    • \\d:匹配任何数字字符(0-9)。
    • \\D:匹配任何数字字符。
    • \\w:匹配任何字母、数字或下划线(A-Z、a-z、0-9 和 _)。
    • \\W:匹配任何字母、数字或下划线的字符。
    • \\s:匹配任意空白字符(如空格、制表符、换行符等)。
    • \\S:匹配任何空白字符。
  2. 自定义字符集:

    正则表达式支持使用[]来自定义字符集,用于匹配单一字符,比如:[abc] 匹配字符abc

    使用**-**来指定字典顺序的前后范围,比如:[0-9] 匹配任意数字;[a-z] 匹配任意小写字母;[A-Za-z] 匹配任意字母

  3. 反向字符类(排除指定字符

    在字符类 [] 中使用 ^ 作为第一个字符(紧跟‘[’之后才会生效),表示匹配不在该集合中的字符。示例如下

    • [^a-z]:匹配非小写字母的任意字符
    • [^0-9]:匹配非数字的任意字符
    • [^aeiou]:匹配非元音字母的任意字符
    // 组合使用示例:匹配不含字母但必须包含数字的字符串
    std::regex no_letters_but_digits(R"(^[^A-Za-z]*[0-9]+[^A-Za-z]*$)");
    

2.3 重复字符匹配

在正则表达式中,特殊字符*+?被称为量词,用于匹配某个字符是否多次重复出现的情况。

  1. *(星号)

    表示出现零次或多次。用于匹配此符号前一个字符零次或多次,比如:a* 可以匹配到 空字符串aaaaaa 等。

  2. +(加号)

    表示出现一次或多次。用于匹配此符号前一个字符一次或多次,比如:a+可以匹配到aaaaaa` 等,但不会匹配空字符串

  3. ?(问号)

    表示出现零次或一次。用于匹配此符号前一个字符零次或一次,比如:a? 可以匹配到 空字符串或者 a

除此之外,还可以使用**{}**来指定出现次数的方位,格式为{min, max},即匹配此符号前一个字符至少min次,至多max次,可省略其中的,和后一个max数值:

  1. {n}

    用于匹配此符号前一个字符正好n次,比如:a{3} 只能匹配到aaa

  2. {min, }

    用于匹配此符号前一个字符至少min次,比如:a{3, } 可以匹配到aaaaaaaaaaaa等。

  3. {min, max}

    用于匹配此符号前一个字符至少min次,至多max次,比如:a{3, 5} 只能匹配到aaaaaaaaaaaa

2.4 边界匹配

在正则表达式中,可以单独指定匹配文本的开头或结尾。分别使用**锚点^来指定开头,使用锚点$**来指定结尾

  1. ^

    将这个符号放在文本首位,表明文本在此开头。用于匹配字符串的开头,比如:正则表达式^abc匹配以abc开头的任意文本abc1abcd

  2. $

    将这个符号放在文本末尾,表明文本在此结尾。用于匹配字符串的结尾,比如:正则表达式abc$匹配以abc结尾的任意文本1abcdabc

锚点还可以混合使用,同时指定文本的开头和结尾,比如:^abc$ 将只匹配字符串abc。还可以更复杂的混合使用,比如:^abc.*123$ 就可以匹配以abc开头和123结尾的任意文本了。

锚点除了这两个最常用的,还有很多指定更多特殊情况的,比如以下四种:

  1. \b

    用于匹配文本中指定的字母字符串(单词)有边界的情况。有\b代表必须有边界,边界是指无任意字符,当然可以是空格。

    比如:正则表达式 \babc 会匹配abc前面有边界的情况,如xyz abc(abc前面有空格作边界,无其他字符相连)、abcdef(abc前面无其他字符相连,后面不用管),而不能匹配abclabc;正则表达式 \babc\b 会匹配abc前后有边界的情况,如abcxyz abc nnn,但不会匹配 111abcabcddd.

  2. \B

    \b的情况相反,用于匹配文本中指定的字母字符串(单词边界的情况。比如:正则表达式 \Babc 会匹配xabc(abc前面无边界) ,但不会匹配abc

  3. \A

    用于匹配字符串的绝对开头,与 ^ 的行为相似,但是 ^ 在多行模式下可能匹配每行的开头,而 \A 始终匹配整个字符串的开头。比如:\Aabc 只会匹配以 “abc” 开头的字符串。

  4. \Z

    用于匹配字符串的绝对结尾,与 $ 的行为相似,但是 $ 在多行模式下可能匹配每行的结尾,而 \Z 始终匹配整个字符串的结尾。比如:\Z123 只会匹配以 123 结尾的字符串。

2.5 分组和选择

正则表达式通过 () 可以将多个字符组合为一个组,可以对一个组的字符进行统一操作,比如:(ab)+ 可以匹配 abababababab 等。

正则表达式使用 | 表示选择,可以理解为逻辑中的或,比如: (a|b) 表示匹配字符 ab

3. C++<regex>标准库的基本使用

<regex>类是C++11引入的标准库,需要包含头文件#include <regex>,并使用命名空间std

官方中文文档点这里传送。

3.1 常用类和方法

  • std::regex: 表示一个正则表达式。它提供了存储和操作正则表达式的能力。
  • std::smatch: 用于存储 std::regex_match 函数的结果。这是一个用于匹配字符串的结果类型,通常使用于 std::string
  • std::cmatch: 与 std::smatch 类似,但用于处理 C 风格字符串(C-strings)。
  • std::regex_search: 用于在字符串中搜索与正则表达式匹配的部分。
  • std::regex_match: 用于检查一个字符串是否完全匹配给定的正则表达式。
  • std::regex_replace: 用于替换字符串中与正则表达式匹配的部分。

3.2 创建正则表达式

使用std::regex类来声明一个正则表达式的匹配模式

示例:

/// 声明一个正则表达式,用于之后匹配一个或多个小写字母  
std::regex pattern("[a-z]+");
/// 只禁止输入_,其他字符不受影响
std::regex no_underscore(R"(^[^_]*$)");

注意:C++中可以通过对字符串使用**R"( )"**修饰来告诉编译器保持字符串原样,不处理转义字符。前面说过,使用特殊字符需要使用\进行双重转义。

而这一般会用在正则表达式、文件路径、JSON/XML数据等,普通字符串一般没必要使用。

std::regex re("\\d+");  // 普通字符串:双重转义后,实际传递的正则是 "\d+"
std::regex re(R"(\d+)"); // 原始字符串:直接传递正则 "\d+"

3.3 匹配

使用**std::regex_match()来检查整个字符串**是否完全匹配正则表达式。

第一个参数为目标字符串,第二个参数为指定正则表达式。匹配返回true,否则返回false。

示例:

std::string str = "hello";  
std::regex pattern("hello");  if (std::regex_match(str, pattern)) {  std::cout << "完整匹配成功!" << std::endl;  
} else {  std::cout << "不匹配。" << std::endl;  
}  

使用**std::regex_search()**查找字符串中是否存在与模式匹配的子字符串。

第一个参数为目标字符串,第二个参数为指定正则表达式。匹配返回true,否则返回false。

std::string str = "hello world";  
std::regex pattern("world");  if (std::regex_search(str, pattern)) {  std::cout << "找到匹配的部分!" << std::endl;  
} else {  std::cout << "未找到匹配。" << std::endl;  
}  

3.4 捕获组

在正则表达式中用括号()包围一段模式来捕获文本中符合格式的子字符串,被称为捕获组。当正则表达式包含捕获组时,可以通过 std::smatchstd::cmatch 来保存匹配的结果。且要注意在声明正则表达式时使用**关键字R**来激活捕获组。

std::smatchstd::cmatch 对象放在std::regex_match()第二个参数。

示例:

std::string str = "2023-10-08";  
std::regex pattern(R"(\d{4})-(\d{2})-(\d{2})"); // 分别捕获年、月、日格式  /// 创建 smatch 对象以保存匹配结果 
std::smatch match;  
if (std::regex_match(str, match, pattern)) {  std::cout << "年: " << match[1] << ", 月: " << match[2] << ", 日: " << match[3] << std::endl;  
}  

3.5 替换

使用 std::regex_replace() 替换匹配部分。

第一个参数为目标字符串,第二个参数为指定正则表达式,第三个参数为替换的字符串。替换成功后返回替换后的字符串,否则返回原字符串。

示例:

std::string str = "I love cats and cats are great.";  
std::regex pattern("cats");  
std::string replaced = std::regex_replace(str, pattern, "dogs");  std::cout << "替换后的字符串: " << replaced << std::endl;  

3.6 指定正则选项

<regex>允许在创建 std::regex对象时,通过第二个参数指定一些正则选项,使用std::regex_constants 命名空间中的常量来指定选项。

  • std::regex_constants::icase:忽略大小写

    在匹配时,忽略字符的大小写。

  • std::regex_constants::multiline:多行匹配

    在多行字符串中,^$ 匹配每行的开始和结束,而不仅仅是整段字符串的开始和结束。

  • std::regex_constants::dotall:点号匹配换行符

    . 匹配的任意字符中增加换行符。

  • std::regex_constants::ECMAScript:使用 ECMAScript 语法

  • std::regex_constants::basic:使用基本的 POSIX 语法

  • std::regex_constants::extended:使用扩展的 POSIX 语法

注意:可以使用|来组合多个选项

示例

/// 只禁止输入_,其他的可以输入
std::regex no_underscore(R"(^[^_]*$)");/// 忽略大小写
std::regex pattern("hello", std::regex_constants::icase);  /// 使用基本的 POSIX 语法
std::regex pattern("hello\\s\\(world\\)", std::regex_constants::basic);/// 忽略大小写并且支持多行匹配
std::regex pattern("hello", std::regex_constants::icase | std::regex_constants::multiline);

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV CUDA模块设备层-----在 GPU上计算反双曲正切函数atanh()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 对输入的 uchar1 像素值&#xff08;范围 [0, 255]&#xff09;&#xff0c;先归一化到 [0.0, 1.0] 浮点区间&#xff0c;然后计算其 反双曲正切…

抢占西南产业高地:入驻成都芯谷金融中心文化科技产业园的价值

入驻成都芯谷金融中心文化科技产业园&#xff0c;对企业而言具有显著的战略价值&#xff0c;主要体现在以下几个方面&#xff1a; 产业聚集效应与协同发展 产业链完善&#xff1a;成都芯谷聚焦集成电路、新型显示、人工智能等核心产业&#xff0c;入驻企业可享受完善的产业链…

领域驱动设计(DDD)【2】之项目启动与DDD基本开发流程

文章目录 一 项目背景与目标二 核心需求分析初步需求详细分析需求总结表 三 DDD核心概念与开发流程领域和领域专家领域驱动设计开发流程 四 潜在扩展需求 一 项目背景与目标 项目定位 开发基于SaaS的企业管理系统&#xff0c;聚焦软件服务企业的细分市场&#xff0c;功能需求包…

深度融合数智化,百胜软件联合华为云加速零售行业转型升级

当前&#xff0c;企业数字化转型纵深推进&#xff0c;满足企业数智化全阶段、全场景的需求变得尤为关键。为此&#xff0c;华为云携手上万家伙伴共同发起第三届828 B2B企业节&#xff0c;依托云底座为企业数智化供需“架桥”“铺路”&#xff0c;加速企业智改数转&#xff0c;助…

《HTTP权威指南》 第4章 连接管理

带着问题学习&#xff08;通常是面试考点&#xff09; HTTP是如何使用TCP连接的TCP连接的时延、瓶颈及存在的障碍HTTP的优化&#xff0c;包括并行连接、keep-alive&#xff08;持久连接&#xff09;和管道化连接管理连接时应该和不应该做的事 TCP连接 TCP的数据通过IP分组&am…

StartUML入门级使用教程——画Class类图

一、破解安装StartUML StarUML建模工具最新版破解安装详细教程https://blog.csdn.net/m0_74146638/article/details/148709643?spm1001.2014.3001.5502 二、类图实战 1.主界面 ​ 默认打开starUML后&#xff0c;会默认进入类图模式&#xff0c;各模块区域功能如下&#x…

中科亿海微SoM模组——FPGA+DSP核心板

FPGADSP核心板是基于中科亿海微EQ6HL130型FPGA芯片搭配国产DSP开发的高性能核心板卡。对外接口采取邮票孔连接方式&#xff0c;可以极大提高信号传输质量和焊接后的机械强度。核心板卡的系统框图如下图所示。 图 FPGADSP核心板系统框图 FPGA采用中科亿海微136K LUT资源EQ6HL130…

CentOS 7 虚拟机网络配置异常 典型问题:启动了NetworkManager但是network无法启动

问题背景 在 VMware 虚拟机中使用 CentOS 7 时&#xff0c;出现以下网络问题&#xff1a; 命令行重启网络服务失败&#xff0c;提示 RTNETLINK answers: File exists 等冲突错误图形界面网络设置无法打开&#xff0c;提示需要启动 NetworkManager网卡 ens33 无法获取 IPv4 地…

细节/数学/滑动窗口

题目意思&#xff1a; 判断字符串是否可以按照题目条件缩短。 思路&#xff1a; 用栈的思想写&#xff0c;对每一次的大小写都进行滚动判断。 tips&#xff1a; 这里面要注意的东西就有一点多了&#xff0c;首先是字符串的遍历问题auto更方便&#xff0c;其次是对小写和大…

WebeServer实现:学到了哪些东西

前言 这里话就是总结一下之前没讲过的一些东西 系统调用 accept与accept4   当我们调用accept接收一个新的fd的时候&#xff0c;往往需要在调用fcntl将这个fd变成非阻塞IO,那么有没有一个系统调用可以一次性做完这两件事呢&#xff0c;有的有的就是accept4. // accept 函数…

React 虚拟dom

JSX创建出ReactElement对象 最终形成一个JS树 将React.createElement对象转为真实DOM的方法使用render函数 为什么要虚拟 dom 状态难以跟踪 ## 操作真实dom开销大 &#xff0c;并且操作会引起频繁的回流和重绘&#xff0c;并且不涉及批处理 声明式编程 从虚拟dom向真实dom去…

Spring MVC异常处理机制

Spring MVC提供了多种异常处理机制,以下是核心处理方式及实现方法: 一、局部异常处理(Controller级别) @ExceptionHandler注解 在Controller内部定义异常处理方法,捕获当前控制器抛出的指定异常。@Controller public class UserController {@GetMapping("/test"…

MySQL 8.x配置MGR高可用+ProxySQL读写分离(一):MGR构建MySQL高可用

#作者&#xff1a;stackofumbrella 文章目录 简介MGR优点MGR缺点MGR适用场景单主模式和多主模式组复制介绍组复制插件架构图单主模式多主模式配置主机名解析安装MGR插件 MGR故障转移恢复MGR集群 简介 MGR&#xff08;MySQL Group Replication&#xff09;是MySQL 5.7.17版本诞…

保安员证考试的理论知识部分,重点考查的法律法规具体有哪些?

保安员证考试理论知识部分&#xff0c;重点考查的法律法规主要有以下几种&#xff1a; 《保安服务管理条例》&#xff1a;作为保安行业的专门法规&#xff0c;是考试核心。重点考查保安服务活动规范&#xff0c;如保安服务的范围、资质要求等&#xff1b;保安员的权利与义务&am…

【好用但慎用】Windows 系统中将所有 WSL 发行版从 C 盘迁移到 非系统 盘的完整笔记(附 异常处理)

&#x1f680; 将所有 WSL 发行版从 C 盘迁移到 I 盘的完整教程&#xff08;含 Podman / NVIDIA Workbench / Ubuntu 等&#xff09; 【无标题】使用 Chocolatey 安装 WSL 管理工具 LxRunOffline-CSDN博客 免责声明 重要提示 在执行 WSL 迁移操作前&#xff0c;请务必仔细阅读…

Oracle APEX 通过rtf模板下载PDF文件(BIP)

1. 上传模板文件 共享组件 > 报表布局 2. 编写SQL文 共享组件 > 报表查询 报表布局中选择1中设置完的报表布局&#xff0c;然后编写SQL文提供数据 3. 添加下载按钮 在页中添加一个下载按钮&#xff0c;添加动态操作&#xff0c;选择打印报告 4. 下载PDF文件 点击Pri…

Web Seach 搜索 MCP 启动!

&#x1f680; 开启你的 AI 助手搜索能力&#xff01;开源 Web 搜索 MCP 服务器上线&#xff01; 在 ChatGPT、Claude 等 AI 工具成为生产力新核心的今天&#xff0c;我们往往面临一个尴尬的问题&#xff1a;模型不知道最新的网络信息。虽然 GPT-4o 和 Claude 支持联网功能&am…

005微信小程序npm包_全局数据共享和分包

npm包_全局数据共享和分包 1. 使用npm包1.1 Vant Weapp1.2 API Promise化 2. 全局数据共享3. 分包3.1 分包的加载规则3.2 分包的体积限制3.3 使用分包3.3 独立分包3.4 分包预下载 1. 使用npm包 小程序对npm进行了支持与限制&#xff0c;限制如下&#xff1a; 不支持依赖于 No…

DPO直接偏好函数的学习解读

DPO, Direct Preference Optimization&#xff0c;采用直接优化策略满足人类偏好&#xff0c;使得LLM对于给定输入&#xff0c;生成能用输出的概率高于生成不能用输出的概率。 1&#xff09;DPO优化目标 在DPO训练过程中&#xff0c;模型通过最大化可用回答相对于不可用回答的…

【开源初探】基于 Qwen2.5VL的文档解析工具:docext

源码地址&#xff1a; https://github.com/NanoNets/docext 概述 docext 是一个由视觉语言模型&#xff08;vlm&#xff09;提供支持的全面的本地文档智能工具包。vlm 使用的是基于 Qwen2.5VL-3B 的模型&#xff0c;应该是在此模型基础上进行的微调。 它提供了三个核心功能&…