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

序言

 正则表达式,简而言之就是用来匹配指定模式字符串的工具,在计算机的世界中,它发挥着很大的作用,比如编译器的词法分析,注册时验证密码的复杂度,爬虫爬取固定格式的数据时等场景都要用到。那么本篇的目的就是能够让大家快速上手正则表达式,并学会相关的接口。下面将先从使用规则入手,先上手正则表达式,再介绍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.mzph.cn/news/860032.shtml

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

相关文章

【SpringCloud-Seata源码分析3】

文章目录 事务的提交客户端提交流程服务端提交流程客户端删除undo_log 事务回滚客户端事务回滚服务端回滚事务 事务的提交 前面两篇我们分析了seata的TC初始化和TM,RM初始化&#xff0c;并且事务准备阶段源码及业务Sql执行&#xff0c;下面我们分析事务的提交源码。 客户端提…

如何应对 Android 面试官 -> MVVM 实战一个新闻客户端 (中)

前言 本章我们基于重构的方式进行一个 MVVM 的实战&#xff0c;我们将一个新闻列表的普通实现&#xff0c;一步一步的改造成 MVVM 的架构模式&#xff0c;一共分为上中下三个章节&#xff0c;本章继续上一章&#xff0c;开始中篇的讲解&#xff1b; 控件化 我们本章向控件化进…

2024年华东杯B题数学建模论文:基于车辆运动学转弯模型的自动驾驶规划问题

摘要 随着自动驾驶技术的发展&#xff0c;车辆转弯问题成为关键挑战。本文针对自动驾驶车辆在转弯过程中的数学建模、路径规划及避障策略进行了深入研究&#xff0c;旨在提升自动驾驶车辆的行驶安全性与效率。 针对问题1&#xff0c;对于四轮前轮驱动车辆的转弯问题&#xff0c…

【C++LeetCode】【热题100】两数相加【中等】-不同效率的题解【1】

题目&#xff1a; 暴力方法&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNo…

常见硬件工程师面试题(二)

大家好&#xff0c;我是山羊君Goat。 对于硬件工程师&#xff0c;学习的东西主要和电路硬件相关&#xff0c;所以在硬件工程师的面试中&#xff0c;对于经验是十分看重的&#xff0c;像PCB设计&#xff0c;电路设计原理&#xff0c;模拟电路&#xff0c;数字电路等等相关的知识…

ps基础入门

1.基础 1.1新建文件 1.2创建指定形状 1.4移动工具 1.41移动画布中的任意元素 1.42移动画布 1.43修改画布大小 1.44修改图像大小 1.5框选工具 1.6矩形工具 1.7图层 1.71图层颜色修改 1.72…

Spring事务介绍、Spring集成MyBatis

目录 1.Spring的事务1.1 什么是事务&#xff1f;1.2 事务的特性&#xff08;ACID&#xff09;1.3 Spring 事务实现方式有哪些&#xff1f;1.4 Spring事务管理接口介绍1.4.1 PlatformTransactionManager:事务管理接口1.4.2 TransactionDefinition:事务属性事务管理器接口1.4.3 T…

《昇思25天学习打卡营第1天|ghqt》

参与这个类活动&#xff0c;我会坚持完成它的。目前MindSpore文档里面的内容还看的不是很懂&#xff0c;希望自己在能不断进步。 第一天学到的内容—— 昇腾应用使能&#xff1a;华为各大产品线基于MindSpore提供的AI平台或服务能力MindSpore&#xff1a;支持端、边、云独立的…

HarmonyOS开发 弹窗组件

1.HarmonyOS开发 弹窗组件 弹窗是移动应用中常见的一种用户界面元素&#xff0c;常用于显示一些重要的信息、提示用户进行操作或收集用户输入。ArkTS提供了多种内置的弹窗供开发者使用&#xff0c;除此之外还支持自定义弹窗&#xff0c;来满足各种不同的需求。 1.1. 示例 1.…

STM32G070休眠例程-STOP模式

一、简介 主控是STM32G070&#xff0c;在低功耗休眠模式时采用Stop0模式&#xff0c;通过外部中断唤醒&#xff0c;唤醒之后&#xff0c;即可开启对应的功能输出&#xff0c;另外程序中设计有看门狗8S溢出&#xff0c;这个采用RTC定时6S周期唤醒去喂狗&#xff0c;RTC唤醒喂狗的…

在线样机生成器,制作精美的电脑手机壁纸图片展示

在线样机生成器&#xff0c;可以制作精美的电脑手机壁纸图片展示。在线样机生成器支持不同的模型如浏览器、手机、笔记本电脑、手表等结合使用&#xff0c;帮助用户快速生成样机展示图片。下面小编就来和大家分享一款免费的在线样机生成器-壁纸样机生成器。 壁纸样机生成器是一…

观测云「可观测性解决方案」荣耀登入华为云官网

继成功上架华为云云商店联营商品后&#xff0c;「观测未来可观测性解决方案」已进一步正式登陆华为云官网&#xff0c;标志着双方合作的深化与拓展。这一全新上架的解决方案是观测云技术实力的集大成之作&#xff0c;为企业提供了一个全面升级的数字化监控观测服务。 观测云&am…

LeetCode 算法:二叉树的直径 c++

原题链接&#x1f517;&#xff1a;二叉树的直径 难度&#xff1a;简单⭐️ 题目 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由…

【后端】Nginx+lua+OpenResty高性能实践

文章目录 9. HTTPS安全认证9.1 证书9.2 证书获取方式9.3 自签证书-openssl工具9.4 Nginx配置HTTPS 10. websocket转发配置 【后端&网络&大数据&数据库目录贴】 9. HTTPS安全认证 http协议问题&#xff1a; 明文传输&#xff0c;有被第三方截取到数据信息的风险 &a…

Java代码操作MySQL数据库——JDBC编程

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

LangChain入门学习笔记(六)—— Model I/O之Output Parsers

当大模型产生输出返回后&#xff0c;它的内容更像是一段平铺的文字没有结构。在传给下游节点处理时可能并不能符合输入要求&#xff0c;LangChain提供了一套机制使得模型返回的内容可以按照开发者定义的那样结构化。 在官网文档中可以看到LangChain提供了丰富的输出解析器&…

二叉树-左叶子之和(easy)

目录 一、问题描述 二、解题思路 三、代码实现 四、刷题链接 一、问题描述 二、解题思路 此题属于树遍历的简单题&#xff0c;用递归深度遍历的方式&#xff0c;当遇到左叶子结点(在递归函数中加上一个判断当前结点是左结点还是右结点的标记位)&#xff0c;此时加上当前结点…

数字图像处理实验报告小论文(Matlab语言)

1.课题分析 在当今信息化社会&#xff0c;图像处理技术已成为众多领域不可或缺的一部分&#xff0c;从医学影像分析到安防监控&#xff0c;再到日常生活中的图片美化&#xff0c;图像处理技术都发挥着至关重要的作用。本次课题主要聚焦于图像灰度处理、图像小波变换和图像分割这…

Python基础系列教程:从零开始学习Python

Python有很多功能强大的机器学习和大数据分析包&#xff0c;适合对大数据和人工智能感兴趣的同学学习。要想了解一门语言&#xff0c;首先需要了解它的语法。本文将介绍Python的一些基础语法&#xff0c;包括数据类型、变量类型、条件控制、循环结构等内容。废话少说&#xff0…

第二十四节:带你梳理Vue2 : Vue具名插槽/作用域插槽/v-slot指令

1. 具名插槽 1.1 没有使用具名插槽的问题 有的时候我们在使用子组件时,在子组件模板上不同的位置插入不同的内容, 只有一个插槽显然没法满足我们的需求,看示例: 需求如下: 子组件是一篇文章的结构父组件在调用子组件是给文章插入标题,正文,时间信息 示例代码如下: <di…