【C++进阶之路】C++11——正则表达式

news2024/7/4 6:14:40

序言

 正则表达式,简而言之就是用来匹配指定模式字符串的工具,在计算机的世界中,它发挥着很大的作用,比如编译器的词法分析,注册时验证密码的复杂度,爬虫爬取固定格式的数据时等场景都要用到。那么本篇的目的就是能够让大家快速上手正则表达式,并学会相关的接口。下面将先从使用规则入手,先上手正则表达式,再介绍C++11库中给出的接口,编写出能够匹配指定规则字符串的正则表达式,因此就算不懂C++也能学会使用正则表达式。

一、基本规则

测试工具

推荐一个方便进行正则表达式测试的网站:https://regex101.com,这一个就够了。

在这里插入图片描述

说明:在Vscode下按下 CTRL + F,以及网页代码的编写界面中 也可以使用正则表达式进行测试,感兴趣的读者可自行了解。


先介绍一下使用此网站匹配的效果,即当输入字符串时,如果匹配正则表达式的内容,则会以高亮的形式显示出来,如下图。

在这里插入图片描述

限定符

  • 一般来说,限定符限定是前面的字符的出现次数,通常使用的有+,*,?,{n,m},{n,} ,{n}

先来看+表示限制前面的字符出现1次或者多次。举个例子,当使用a+去匹配aabb时,aa的部分会以高亮的形式显示出来,如下图。

在这里插入图片描述
再来看*表示前面的字符出现任意次,比上面的+的区别是可以出现0次。举个例子,当使用ca*bb去匹配cbb时,cbb会以高亮的形式显示出来,原因就在于a*,表示a可以出现0次,效果如下图。

在这里插入图片描述
接着来看,表示前面的字符出现1次或者0次。,当使用ca?bb去匹配cbb时,cbb会以高亮的形式显示出来,效果如下图。
在这里插入图片描述
最后来看,{n,m},{n,} ,{m}分别表示前面的字符出现n到m次,至少出现n次,m次,可以帮助更好地控制字符的出现次数。举个例子,使用的匹配字符串为aaaaa,当分别使用a{3}a{3,}a{3,4}匹配时,分别为a出现3次,a出现至少3次,a出现3次到4次。效果如下图。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

除此之外,这里再多介绍一个基本上是万能的字符.,即表示匹配除换行符之外的任意一个字符。比如说hell. world,就可以完全匹配hello world,效果如下图,并且一般来说常见的组合是.*即表示匹配除换行符之外的字符任意次。

在这里插入图片描述

在这里插入图片描述

介绍到这里你或许会觉得正则表达式这么简单么,当然不是,上面所说的仅仅是很简单的用法而已,还要搭配着其它的正则表达式的字符进行使用才有更高阶的玩法,下面介绍一些可以进行搭配使用的字符。

定位符

 常见的一般来说有^$,分别表示匹配行首的字符串和行尾的字符串,这个十分简单,举个例子,分别使用 ^aa和aa\$分别去匹配aaaa,分别只会匹配前面aa后面aa,效果如下图。

在这里插入图片描述
在这里插入图片描述

表达式

常见的一般来说有()子表达式,存放的是指定要求的匹配模式,[]中表达式,存放的是字符的范围。

首先来看(),光看理论是不容易理解的,直接看例子,比如说(aa)?bb,其中aa表示可以匹配0次或者一次,去匹配aabbbb,都能匹配成功,效果如下图。

在这里插入图片描述

除此之外,这里再介绍一个逻辑字符 |,表示或的意思,配合()可以用来匹配指定条件的字符串,比如(aa|ac)bb,就可以匹配aabb以及acbb,效果如下图,在筛选出固定后缀的字符串时比较适用。

在这里插入图片描述

再来看[],同理还是直接看例子,比如b[az]c,就可以匹配bac以及bzc,效果如下图。

在这里插入图片描述

除此之外,这里也要多介绍一个^表示逻辑取反的意思,比如a[^be]c ,可以匹配除了abc和aec之外的a.c模式的字符串,效果如下图。

在这里插入图片描述

补充:除了放指定满足要求的字符外,还可以放字符的范围,比如[a-z]表示所有的小写字母,[0-9]表示所有的数字字符,等等。

等价替换

在正则表达式中,[]中存放表示范围的字符或许太常用了,比如[a-z][0-9],所以采用了一些特殊字符将其等价替换,常见的有\d,对应着[0-9],与之相反的是\D,对应着[^0-9] , \w对应着[a-z],与之相反的是\W对应着[^a-z] \s对应着 [ \f\n\r\t\v],即可以匹配任意的空格符,制表符,换行符等,与之相反的是\S,对应着[^\f\n\r\t\v] 。举个例子,比如\d\w\s,即可匹配小写字母字符 + 数字字符 + 换行符默认的字符串,效果如下图。
在这里插入图片描述

 读到了这里相信各位已经对正则表达式有了一个基本的认识,恭喜你简单入门了! 不过还需各位进行实践解锁更多玩法,下面将介绍C++11提供的正则表达式的基本接口。

二、接口介绍

 C++11中引入了<regex>库,即引入了关于正则表达式的调用接口的库,主要包含std::regex类用于存放正则表达式,std::smatch类用于存放匹配的结果,std::regex_match进行全文匹配,std::regex_search进行搜索匹配项,std::regex_replace用于替换与正则表达式匹配的字符串。展开来讲还有很多,感兴趣的读者可自行到官方文档——cplusplus了解。

1.正则表达式

 regex,即正则表达式对象,用于设置目标字符串的正则表达式,用字符串进行初始化和赋值,里面包含一些接口mark_count获取子表达式的数量,flags用于设置匹配的模式,imbue与getloc设置与获取区域设置等等。

说明:

  • 子表达式,简单理解为正则表达式中一对()即为一个子表达式。
  • 匹配模式,比如设置为icase,即为忽略大小写。
  • 区域设置,与时间,地区,语言,字符集等内容相关。比如设置UTF-8,GBK,ASCII编码等不同的字符集。

2.容器

  • smatch,存放匹配结果的容器,用于匹配string类型的对象,类似的还有cmatch
  • 如果没有匹配成功则为空;如果匹配成功,下标为0处存放的是匹配的结果,下标为1处存放的是第一个子表达式,下标为2处存放的是第二个子表达式,以此类推。
  • 常用的接口有prefixsuffix分别用于获取匹配结果的前缀和后缀,lengthposition分别用于获取指定下标处的字符串的长度和在原字符串的位置,str[]用于获取指定下标处的匹配结果,emptyready分别用于检测是否为空和是否在之前被调用过。

3.全文匹配

  • 函数名——regex_match
  • 参数
    • string,匹配的字符串。
    • smatch,输出型参数,存放匹配的结果。
    • regex,正则表达式对象。
  • 返回值,匹配成功为true,反之为false。

demo

#include<iostream>
#include<regex>
#include<string>
using namespace std;
int main()
{
	smatch res;//存放结果
	string str = "subject";
	string pattern("(sub)(.*)");
	regex r(pattern);	
	bool ret = regex_match(str,res,r);
	if (ret)
	{
		cout << "匹配成功" << endl;
		cout << "匹配的结果为:" << res[0] << endl;
		cout << "第一个子表达式为:" << res[1] << endl;
		cout << "第二个子表达式为:" << res[2] << endl;
	}
	else
	{
		cout << "匹配失败" << endl;
	}
	return 0;
}

output

在这里插入图片描述

  • 拓展:使用正则表达式获取解析Http协议字段
#include <iostream>
#include <string>
#include <regex>
#include <iterator>
using namespace std;
int main() 
{
	//全文匹配,使用子表达式存放解析结果,只提取出请求方法,域名信息,查询字段(可能有或者没有)。
	smatch res;
	string str = "GET /blog.csdn.net/Shun_Hua?user=xiaoming&pass=123123 HTTP/1.1\r\n";
	string pattern("(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\?(.*))? HTTP/1\\.[01](?:\r\n|\n)?");
	//(GET|HEAD|POST|PUT|DELETE)请求方法的匹配。
	//([^?]*)表示匹配非问号字符串,用于获取域名。
	
	//\\?,首先?是特殊字符,要想正常匹配得使用\进行转义,\也是特殊转义字符,要想使用得再使用\进行转义。
	//(.*),.*是对任意字符串进行匹配。
	//?:\\?,表示不提取?到res中
	//(\\?(.*))?,表示子表达式出现0次或者1次。
	//(?:\\?(.*))?,子表达式出现0次或者1次,不提取?,提取(.*)到res中。
	
	//HTTP/1\\.[01],匹配版本号。

	//(?:\r\n|\n)?,同理表示匹配\r\n或者\n,0次或者1次,且不提取。

	regex r(pattern);
	bool ret = regex_match(str, res, r);
	if (ret)
	{
		cout << "匹配成功" << endl;
		for (auto e : res)
		{
			cout << e << endl;
		}
	}
	else
	{
		cout << "匹配失败" << endl;
	}
	return 0;
}

output

在这里插入图片描述

4.搜索

  • 函数名——regex_search
  • 参数
    • string,匹配的字符串。
    • smatch,输出型参数,存放匹配的结果。
    • regex,正则表达式对象。
  • 返回值,匹配成功为true,反之为false。

demo:

#include <iostream>
#include <string>
#include <regex>
int main()
{
	string str("this subject has a marine.");
	smatch res;//存放结果
	regex r("subject"); 
	bool ret = regex_search(str, res, r);
	if (ret)
	{
		cout << "匹配成功" << endl;
		cout << "匹配的结果为:" << res[0] << endl;
		cout << "前缀为:" << res.prefix() << endl;
		cout << "后缀为:" << res.suffix() << endl;
	}
	else
	{
		cout << "匹配失败" << endl;
	}
	return 0;
}

output:

在这里插入图片描述

5.替换

  • 函数名——regex_replace
  • 参数
    • string,匹配的字符串。
    • regex,正则表达式对象。
    • string,用于替换的字符串。
  • 返回值,匹配成功为true,反之为false。

demo

#include <iostream>
#include <string>
#include <regex>
#include <iterator>
using namespace std;
int main()
{
	string s("there is subject in the string\n");
	regex e("subject"); 
	string rep = "something";
	cout << std::regex_replace(s, e, rep) << endl;
	return 0;
}

output

在这里插入图片描述

尾序

 本篇介绍了正则表达式的基本使用以及C++11中提供的接口,总的来说入门正则表达式并不难,难的是如何活学活用,剩下就靠各位读者实践解锁更多玩法了,我是舜华,期待与你的下一次相遇!

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

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

相关文章

超市库存管理系统

本系统主要利用C#和SQL建立系统,主要实现一下几个功能:登录、商品管理、供应商管理、库存管理、查询统计和系统管理几个模块。 1.数据库设计 总共有6个表,表名取得比较随意,专业人士开发最好用对应的英文。 用户表(sys_user) 用户表有3个字段:分别为用户名(userName…

如何将一个web端程序打包成一个pc端程序(exe文件)?

如何将一个Web端程序打包成一个PC端程序&#xff0c;例如一个可执行的EXE文件&#xff0c;是许多开发者常见的需求。下面将详细解释如何使用Nativefier工具将Web端程序打包成PC端程序的具体步骤。 目录 下载并安装Node.js验证Node.js和npm的安装安装Nativefier使用Nativefier打…

近2年时间,华为手机上的卫星通信功能发展成怎样了?

自从Mate 50 系列支持北斗卫星短报文功能以来&#xff0c;已经过去了近2年的时间&#xff0c;卫星相关的功能也从最开始的摸索、罕见&#xff0c;逐渐变得成熟、在各品牌旗舰机上常见起来。 那么&#xff0c;这近两年的发展&#xff0c;卫星相关的功能都有了怎样的变化呢&…

HarmonyOS NEXT的发布不仅打破了技术垄断,还保护了国人数据安全

吉祥学安全知识星球&#x1f517;除了包含技术干货&#xff1a;Java代码审计、web安全、应急响应等&#xff0c;还包含了安全中常见的售前护网案例、售前方案、ppt等&#xff0c;同时也有面向学生的网络安全面试、护网面试等。 01-HarmonyOS NEXT 前几天华为发布了最新的鸿蒙…

P8813 [CSP-J 2022] 乘方

题目&#xff1a; P8813 [CSP-J 2022] 乘方 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 提交记录&#xff1a; 记录详情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 个人主页&#xff1a; xuzb 的个人中心 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) AC代码&…

Calibre - 翻译电子书(Ebook Translator)

本文参考教程 &#xff1a;https://bookfere.com/post/1057.html 使用 Ebook Translator 插件&#xff0c;详见&#xff1a; 官网&#xff1a;https://translator.bookfere.comgithub &#xff1a;https://github.com/bookfere/Ebook-Translator-Calibre-Plugin 一、基本翻译 …

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的数字游戏(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

链在一起Chained Together没中文 超好用的一键汉化工具推荐

《链在一起》一款新的可联机冒险跑酷类游戏&#xff0c;游戏里玩家将与你的同伴被链在一起&#xff0c;然后开始你的旅程&#xff0c;在地狱的深处&#xff0c;任务是通过尽可能高的攀登逃离地狱。 每一次跳跃都需要完美的协调才能攀上平台并逃离灼热&#xff0c;穿越众多世界&…

哈哈,CloudFlare 赛博菩萨威武呀,真是想啥来啥!

就在今天明月发现 CloudFlare 赛博菩萨又免费增加了一个新功能&#xff0c;对于广大原创内容为主的博客站长来说是绝对的利好&#xff0c;那就是专门针对 AI 爬虫的自动阻止机器人抓取您的内容以用于模型训练等人工智能应用程序正式上线了。如下图所示&#xff1a; 只需要在 Cl…

【机器学习】机器学习重要方法——深度学习:理论、算法与实践

文章目录 引言第一章 深度学习的基本概念1.1 什么是深度学习1.2 深度学习的历史发展1.3 深度学习的关键组成部分 第二章 深度学习的核心算法2.1 反向传播算法2.2 卷积神经网络&#xff08;CNN&#xff09;2.3 循环神经网络&#xff08;RNN&#xff09; 第三章 深度学习的应用实…

03 Shell编程之循环语句与函数

目录 3.1 for 循环语句 3.1.1 for 语句的结构 3.1.2 for 语句应用示例 1. 根据姓名列表批量添加用户 2. 根据IP地址列表检查主机状态 3.2 使用while循环语句 3.2.1 while语句的结构 3.2.2 while语句应用示例 1. 批量添加规律编号的用户 2. 猜价格游戏 3.3 until 循环语句 3.…

[word] word 如何在文档中进行分栏排版? #媒体#其他#媒体

word 如何在文档中进行分栏排版&#xff1f; 目标效果 将唐代诗人李白的组诗作品《清平调词》进行分栏排版&#xff0c;共分三栏&#xff0c;每一首诗作为一栏&#xff0c;参考效果如下图。

策略模式 + 抽象工厂实现多方式登录验证

文章目录 1、需求背景2、常规想法3、工厂模式 配置文件解耦 策略模式4、具体实现5、其他场景6、一点思考 1、需求背景 以gitee为例&#xff0c;登录验证的方式有多种&#xff1a; 用户名密码登录短信验证码登录微信登录 先写一个登录接口&#xff0c;适配所有方式&#xff…

如何使能PCIe的ASPM?

1. ASPM概述 PCIe总线的电源管理包含ASPM(Active State Power Management)和软件电源管理两方面内容。所谓的ASPM是指PCIe链路在没有系统软件参与的情况下&#xff0c;由PCIe链路自发进行的电源管理方式。如下是PCIe的ASPM的状态机&#xff0c;其L1是强制性的规定&#xff0c;…

Redis入门与应用(1)

Redis的技术全景 Redis是一个开源的基于键值对&#xff08;Key-Value&#xff09;的NoSQL数据库&#xff0c;使用ANSI C语言编写&#xff0c;支持网络&#xff0c;基于内存但支持持久化。它性能优越&#xff0c;并提供多种语言的API。我们可以将Redis视为一个巨大的Map&#x…

Linux 字符型设备 + platform总线 + sysfs设备模型

1 概述 第一部分先简单介绍下字符型设备 platform总线 sysfs设备模型的关系。 1.1 . 字符设备驱动 Linux设备驱动分三种&#xff0c;包括字符设备驱动、块设备驱动和网络设备驱动。字符设备只能按字节流先后顺序访问设备内存&#xff0c;不能随机访问。鼠标、触摸屏、LCD等…

Part 5.2 KMP

KMP 算法可以用来解决模式串匹配问题。 【模板】KMP 题目描述 给出两个字符串 s 1 s_1 s1​ 和 s 2 s_2 s2​&#xff0c;若 s 1 s_1 s1​ 的区间 [ l , r ] [l, r] [l,r] 子串与 s 2 s_2 s2​ 完全相同&#xff0c;则称 s 2 s_2 s2​ 在 s 1 s_1 s1​ 中出现了&…

MQTTX 1.10.0 发布:CLI高级文件管理与配置

MQTTX 1.10.0 版本现已发布&#xff01; 在本次更新中&#xff0c;CLI 版本在文件管理和配置功能方面进行了显著增强。主要更新包括&#xff1a;支持从文件中读取和写入消息、高级配置选项、文本输出模式、以及改进的日志记录。此外&#xff0c;桌面版本现在支持数据库重建&am…

Vue父组件mounted执行完后再执行子组件mounted

// 创建地图实例 this.map new BMap.Map(‘map’) } } ... 现在这样可能会报错&#xff0c;因为父组件中的 map 还没创建成功。必须确保父组件的 map 创建完成&#xff0c;才能使用 this.$parent.map 的方法。 那么&#xff0c;现在的问题是&#xff1a;如何保证父组件 mo…

Twinkle Tray:屏幕亮度控制更智能

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。 ——苏轼 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、软件介绍1、Twinkle Tray2、核心特点 二、下载安装1、下载2、安装 三、使用方法 很高兴你打开…