一篇文章学会正则表达式的语法

news2024/10/5 15:34:22

点击下方关注我,然后右上角点击...“设为星标”,就能第一时间收到更新推送啦~~~

正则表达式(Regular Expression)在代码中常常简写为regex。正则表达式通常被用来检索、替换那些符合某个规则的文本,它是一种强大而灵活的文本处理工具。正则描述了一个规则,通过这个规则可以匹配一类字符串。

为了便于理解,所有示例的正则表达式用“regex=正则”表示,“=”号后面就是正则表达式,匹配到的字符会用颜色标注出来,连续匹配到的字符用一深一浅两种颜色区分。

比如:regex=\d+,其中\d+就是一个正则,它匹配任意多于1个的数字,如下:

fdc5140d45f53e40777025d4a79ede9c.png

学习正则表达式语法,主要就是学习元字符以及它们在正则表达式上下文中的行为。元字符包括:普通字符、标准字符、特殊字符、限定字符(量词)、定位字符(边界字符)。

1、普通字符

字母[a-zA-Z]、数字[0-9]、下划线[-]、汉字,标点符号

匹配字母a可以regex=a

匹配字母b可以regex=b

匹配字母a或者b可以regex=a|b,这个正则引入一个特殊字符“|”,专业名称为“或”,你也可以叫它“竖线”,总之它表示“或”的意思。

匹配字母a或者b或者c可以regex=a|b|c

匹配字母a或者b或者c或者d可以regex=a|b|c|d

明显发现这么写有点傻了,如果匹配所有26个字母,这种写法就太二了。

这里引入两个特殊字符方括号“[ ]”和中划线“-”

“[ ]”,专业名称为“字符集合”,你也可以叫它“方括号”。

“-”,表示“范围”,你也可以叫它“到”,regex=[a-z]匹配从a到z26个字母的任意一个。

那么匹配字母a或者b或者c或者d可以regex=[abcd]

匹配数字1到8的任意数字可以regex=[1-8],这样就不会匹配到0与9这2个数字了,如下:

7799deb8b31ca5ac022b95e7bed0f9fd.png

2、标准字符集合

标准字符集合是能够与“多种普通字符”匹配的简单表达式,比如:\d、\w、\s

匹配数字0到9的任意数字可以regex=[0-9]也可以regex=\d

标准字符集要注意区分大小写,大写是相反的意思

regex=\D,则匹配非数字字符,即不能匹配数字0到9,如下:

581ac5f50cb877d6eefbf8824e4719b7.png

下面是一些常用的标准字符说明

标准字符含义
\d匹配0-9中的任意一个数字,等效于[0-9]
\D匹配非数字字符,等效于[^0-9]
\w匹配任意一个字母、数字或下划线,等效于[^A-Za-z0-9_]
\W与任何非字母、数字或下划线字符匹配,等效于[^A-Za-z0-9_]
\s匹配任何空白字符,包括空格、制表符、换页符,等效于  [\f\n\r\t\v]
\S匹配任何非空白字符,等效于[^\f\n\r\t\v]
\n匹配换行符
\r匹配一个回车符
\t匹配制表符
\v匹配垂直制表符
\f匹配换页符

3、特殊字符

这些字符在正则表达式中表示特殊的含义,比如:*,+,?,\,等等

“\”是转义字符,用于匹配特殊字符

匹配反斜杠“\”可以regex=[\\],因为“\”是特殊字符,所以需要在它前边再加一个“\”进行转义

匹配星号“*”,可以regex=\*,因为“*”是特殊字符,所以需要在它前边再加一个“*”进行转义

下面是一些常用的特殊字符说明,后面都会讲到

特殊字符含义
\转义字符,将下一个字符标记为一个特殊字符
^匹配字符串开始的位置
$匹配字符串结尾的位置
*零次或多次匹配前面的字符或子表达式
+一次或多次匹配前面的字符或子表达式
?零次或一次匹配前面的字符或子表达式
.“点”  匹配除“\r\n”之外的任何单个字符
|
[ ]字符集合
( )分组,要匹配圆括号字符,请使用 “\(”  或 “\)”

4、限定字符(量词)

限定字符又叫量词,是用于表示匹配的字符数量的。

匹配任意1位数字可以regex=\d

匹配任意2位数字可以regex=\d\d

匹配任意3位数字可以regex=\d\d\d

匹配任意16位数字,再这么写就有点傻了

这里引入用于表示数量限定字符“{n}”

{n},n是一个非负整数,匹配确定的n次

注意:regex=\d\d{3}匹配任意4个数字不是6个,量词只对它前面的字符负责,regex=\d\d{3}匹配的内容如下:

6a2588f3448e1d407ffaabb57853dbb4.png

匹配任意16位数字可以regex=\d{16}

匹配任意16位以上的数字可以regex=\d{16,}

匹配任意1到16位以上的数字可以regex=\d{1,16}

d20fb2a562f0438f99ccd2e21d00a4e6.png

从上图,我们可以看到regex=\d{1,16},可以匹配到任意1-16个数字。

下面介绍一下匹配次数中的贪婪模式与非贪婪模式

正则的匹配默认是贪婪模式,即匹配的字符越多越好,非贪婪模式是匹配的字符越少越好,在修饰匹配字数的量词后再加上一个问号“?”即可。

那么同样是上面的字符串,regex=\d{1,16}?匹配到什么呢?

80fbcba9eff32b0acab05b2851a57536.png

因为在{1,16}这个量词后面加上了问号“?”,表示非贪婪模式,所以只能匹配到1个数字,即匹配的字符越少越好。

下面是一些常用的限定字符说明

限定字符含义
*零次或多次匹配前面的字符或子表达式
+一次或多次匹配前面的字符或子表达式
?零次或一次匹配前面的字符或子表达式
{n}n是一个非负整数,匹配确定的n次
{n,}n是非负整数,至少匹配n次
{n,m}n和m是非负整数,其中n<=m;匹配至少n次,至多m次

匹配0个或多个字母A可以regex=A*或者regex=A{0,}

匹配至少一个字母A可以regex=A+或者regex=A{1,}

匹配0个或1字母A可以regex=A?或者regex=A{0,1}

匹配至少一个LOVE可以regex=(LOVE)+

匹配的效果如下:

4f381be57237d1a75b37fcab6de7ee94.png

5、定位字符(字符边界)

定位字符也叫字符边界,标记匹配的不是字符而是符合某种条件的位置,所以定位字符是“零宽的”。

下面是一些常用的定位字符说明

定位字符含义
^匹配字符串开始的位置,表示开始
$匹配字符串结尾的位置,表示结尾
\b匹配一个单词边界

匹配以Hello开头的字符串可以regex=^Hello

77caf652a2f62885477fd143add63bcc.png

匹配以Hello结尾的字符串可以regex=Hello$,如下:

de44c42d52e01204dc997ded82dd8122.png

匹配以H开头以o结尾的任意长度字符串可以regex=^H.*o$,如下:

549b336bd0964cf5bba6e8ca2a239f28.png

\b匹配这样一个位置:前面的字符和后面的字符不全是\w

如果在“hello,hello1 hello hello1 bhello”这个字符串里匹配regex=hello\b,

匹配到的结果如下:

864c440bb24e36e09bb7822b4ad73be9.png

分析以下问题:为什么hello1匹配不了“hello\b”这个正则?

首先\b是一个定位字符,它是零宽的,标识一个位置,这个位置的前面和这个位置的后面不能全是\w,即不能全是字母数字和下划线[A-Za-z0-9_],而hello1的o与1之间的位置前面是o后面是1,前后全是\w,不符合\b匹配的含义,因此hello1不能匹配正则表达式“hello\b”

但是bhello可以匹配“hello\b”这个正则,因为hello的结尾的位置,前面是o,后面是空白,所以符合\b匹配的含义,因此bhello可以匹配“hello\b”这个正则。

6、自定义字符集合

方括号[ ]表示字符集合,即[ ]表示自定义集合,用[ ]可以匹配方括号里的任意一个字符。

regex=[aeiou]匹配“a”,“e”,“i”,“o”,“u”任意一个字符,也就是可以匹配集合[aeiou]的任意一个字符。

需要注意,特殊字符(除了小尖角“^和中划线“-)被包含到方括号中,就会失去特殊意义,只代表其字符本身。

regex=[abc+*?]匹配“a”,“b”,“c”任意一个字符或者“+”,“*”,“?”,即包含在自定义集合中的特殊字符“+”,“*”,“?”失去了特殊含义,只表示其字符本身的意思。

特殊字符小尖角“^,原本含义是匹配字符串的开始位置,如果包含在自定义集合[ ]中,则表示取反的意思。

比如:regex=[^aeiou]匹配“a”,“e”,“i”,“o”,“u”之外的任意一个字符。

中划线“-,在自定义集合[ ]中,表示“范围”,而不是字符“-本身,regex=[a-z],匹配从a到z中26个字母的任意一个。

除小数点“.”外,标准字符集合包含在方括号中,仍然表示集合范围。

regex=[\d.+]匹配0-9的任意一个数字或者小数点“.”或者加号“+”

也就是说\d在自定义集合中仍然表示数字,但是小数点在字符集合中只表示小数点本身,而不是除“\r\n”之外的任何单个字符。

7、选择符和分组

表达式作用
pattern1|pattern2或的关系,匹配左边的pattern1或右边的pattern2
(pattern)匹配pattern并获取这一匹配,并存储
(?:pattern)匹配pattern但不获取匹配结果,也就是不进行存储


regex=x|y,匹配字符x或y。

( )表示捕获组,( )的作用如下:

1、括号中的表达式可以作为整体被修饰,用来表示匹配括号中表达式的次数

regex=(abc){2,3},可以匹配连续的2个或3个abc,如下:

b578f5e15c2d16e3a3679dfffc7bd5df.png

2、括号中的表达式匹配到的内容会存储起来,并可以获取到括号中表达式匹配到的内容

3、每一对括号会分配一个编号,使用( )的捕获根据左括号的顺序从1开始自动编号,编号为0的捕获是整个正则表达式匹配到的文本。

捕获组( )可以把匹配的内容存储起来,那么如何获取( )捕获到的内容呢,下面介绍反向引用。

8、反向引用“\number”

每一对括号会分配一个编号,使用( )的捕获根据左括号的顺序从1开始自动编号。通过反向引用,可以对分组已捕获的字符串进行引用。

“\number”中的number就是组号。

regex=(abc)d\1可以匹配字符串abcdabc,即\1表示把获取到的第一组再匹配一次,如下:

104385cd880e6828117760515e11dd9a.png

(?:pattern)表示非捕获组,匹配括号中表达式匹配到的内容,但是不进行存储匹配到的内容。这在使用 "或" 字符 (|) 来组合一个正则的各个部分是很有用的。

例如:匹配字符“story”或者“stories”,regex=stor(?:y|ies)就是一个比 regex=story|stories更简略的表达式。

9、预搜索(零宽断言)

预搜索,又叫零宽断言,又叫环视,它是对位置的匹配,与定位字符(边界字符)类似。

表达式作用
(?=pattern)断言此位置的后面能匹配表达式pattern
(?<=pattern)断言此位置的前面能匹配表达式pattern
(?!pattern)断言此位置的后面不能匹配表达式pattern
(?<!pattern)断言此位置的前面不能匹配表达式pattern

regex=love (?=story)匹配的结果如下(匹配“love ”后面是story):

a2749aefbb31f7495d612f5557d27dc8.png

regex=love (?!story)匹配的结果如下(匹配“love ”后面不能是story):

301d776e15f4b28a65749b51fc5fe634.png

10、运算符的优先级

正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。

下表的优先级从高到低排序

运算符描述
\转义字符
(),  (?:), (?=), []圆括号和方括号,分组和自定义集合
*,  +, ?, {n}, {n,}, {n,m}限定字符(量词)
^,  $, 标准字符,字符定位字符(边界字符)和字符
|

说明:“|”或操作是优先级最低的,它比普通字符的优先级低。

因此,regex=r|loom匹配“r”或“loom”,如下:

e648543036dfe1acafd1e3e593461941.png

如果想匹配“room”或“loom”,请用括号创建子表达式,regex=(r|l)oom,如下:

9aa050a254efc2efa60f0046f664c3e4.png

最后给大家介绍一下开发中使用正则表达式的流程:

1、分析所要匹配的数据特点,模拟各种测试数据;

2、利用正则工具,写正则表达式与测试数据进行匹配,从而验证你写的正则;

3、在程序里调用在正则工具中验证通过的正则表达式。

在这里给大家推荐一个正则工具“RegexBuddy”,你可以从网上下载,或者在后台回复关键词“正则表达式”获取。

至此,正则表达式的语法介绍完了,大家是不是已经掌握了呢,赶快去体验一下吧。

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

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

相关文章

1. 快速体验 VSCode 和 CMake 创建 C/C++项目

1. 快速体验 VSCode 和 CMake 创建 C/C项目 本章的全部代码和markdown文件地址: CMake_Tutorial&#xff0c;欢迎互相交流. 此次介绍的内容都是针对于 Linux 操作系统上的开发过程. 1.1 安装开发工具 VSCode: 自行下载安装, 然后安装插件 Cmake:在 Ubuntu 系统上, 可以采用 ap…

[k8s] pod的创建过程

pod的创建过程 定义 Pod 的规范&#xff1a; apiVersion: v1 kind: Pod metadata:name: my-pod spec:containers:- name: my-containerimage: nginx:latest创建 Pod 对象&#xff1a; 使用 kubectl 命令行工具或其他客户端工具创建 Pod 对象&#xff1a; kubectl create -f…

【JAVA-Day15】Java 的 do-while 循环语句

Java 的 do-while 循环语句 Java 的 do-while 循环语句摘要引言一、什么是 do-while 循环语句二、do-while 循环语句的语法三、do-while 循环的优势和使用场景优势使用场景 与其他方式相比优势劣势与while循环比较与for循环比较 建议四、总结参考资料 博主 默语带您 Go to New …

90 # 实现 express 请求处理

上一节构建 layer 和 route 的关系&#xff0c;这一节来实现 express 请求处理 application.js const http require("http"); const Router require("./router");function Application() {this._router new Router(); }Application.prototype.get fu…

【C语言】【数据存储】用%u打印char类型?用char存128?

1.题目一&#xff1a; #include <stdio.h> int main() {char a -128;printf("%u\n",a);return 0; }%u 是打印无符号整型 解题逻辑&#xff1a; 1. 原反补互换&#xff0c;截断 -128 原码&#xff1a;10000000…10000000 补码&#xff1a;11111111…10000000…

【初阶数据结构】树(tree)的基本概念——C语言

目录 一、树&#xff08;tree&#xff09; 1.1树的概念及结构 1.2树的相关概念 1.3树的表示 1.4树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 二、二叉树的概念及结构 2.1二叉树的概念 2.2现实中真正的二叉树 2.3特殊的二叉树 2.4二叉树的性质…

【iOS】ViewController的生命周期

文章目录 前言一、UIViewController生命周期有关函数二、执行顺序注意点loadview&#xff1a; 前言 在iOS开发中UIViewController扮演者非常重要的角色&#xff0c;它是视图view和数据model的桥梁&#xff0c;通过UIViewController的管理有条不紊的将数据展示在视图上。作为UI…

XML 和 JSON 学习笔记(基础)

XML Why XML 的出现背景&#xff1a;在实际开发中&#xff0c;不同语言&#xff08;如Java、JavaScript等&#xff09;的应用程序之间数据传递的格式不同&#xff0c;导致它们进行数据交换时很困难&#xff0c;XML就应运而生了&#xff01;&#xff08;XML 是一种通用的数据交…

视频分析【video analytics】的项目的关键因素 -- 如何选择合适的摄像头,存储设备,以及AI推理硬件?

文字大纲 参考指标摄像机存储设备AI 推理硬件参考文献与学习路径参考指标 摄像机 通常的做法是将视频视为一系列图像(帧),并使用仅在图像上训练的深度神经网络模型来执行视频上的相似分析任务。在这篇论文中,我们表明,这种在图像上运行良好的深度学习模型在视频上也会运行…

QT:使用普通按钮、网格布局管理器、标签、行编辑器、水平布局管理器、垂直布局管理器做一个小项目

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> //普通按钮 #include <QGridLayout> //网格布局管理器 #include <QLabel> //标签 #include <QLineEdit> //行编辑器 #include <QHBoxLayo…

core文件的生成与使用

目录 core 设置例子 1例子 2core 名称及目录修改参考 在使用嵌入式系统时&#xff0c;出错后&#xff0c;不好使用 gdb 调试&#xff0c;这时&#xff0c;可让系统生成一个 core 文件&#xff0c;用于查看出错原因 core 设置 要生成 core 文件&#xff0c;需要先设置 core 文…

链表的基本操作(acm模式,中等)

此题自己亲自动手实现难度确实不容易&#xff0c;为了更好的掌握 链表这一结构&#xff0c;还是得自己敲&#xff0c;自己debug,还得多次看&#xff0c;才能脑子清楚&#xff0c;手也熟。 // 本题的删除索引是从1开始&#xff0c;函数实现是从0开始&#xff0c;先说明这一点&a…

基于SSM的高校教师科研信息展示网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

[自用]手推DDPM公式

正向最终呈N(0,1) 逆向可解 用神经网络预测逆向的噪声ε&#xff0c;与正向的噪声做MSE

列属性与数据完整性

1.2 数据类型——值类型 1.2.1 整型 类型字节范围tinyint1-128~127smallint2-32768~32767mediumint3-8388608~8388607int4-231~231-1bigint8-263~263-1 1、无符号整数&#xff08;unsigned&#xff09;&#xff1a;无符号数没有负数&#xff0c;正数部分是有符号的两倍。 例…

解决Qt VS Tools扩展加载预编译Qt库 提示版本不匹配

提示 qmake error:no value for QT_INSTALL_PREFIX/src 原因&#xff1a; qt路径编译时&#xff0c;是硬编码到qmake里的&#xff0c;所以如果挪动了qt的目录&#xff0c;或者是下载其他人预编译的qt库&#xff0c;就会有该提示。 解决方案&#xff1a; qmake同级别路径新建q…

docker 和k8s 入门

docker 和k8s 入门 本文是云原生的学习记录&#xff0c;可以参考以下文档 k8s https://www.yuque.com/leifengyang/oncloud 相关视频教程可参考如下 https://www.bilibili.com/video/BV13Q4y1C7hS?p2&vd_source0882f549dac54045384d4a921596e234 相对于公有云&#x…

6.3、Flink数据写入到MySQL

目录 1、添加POM依赖 2、这一个完整的案例 3、何时批量写入MySQL呢&#xff1f; 4、容错性的保证(精确一次&至少一次) 4.1、 至少一次 4.2、精确一次 1、添加POM依赖 Apache Flink 集成了通用的 JDBC 连接器&#xff0c;使用时需要根据生产环境的版本引入相应的依赖…

哈夫曼编码原理及实现

文章目录 一.哈夫曼编码原理哈夫曼二叉树构建 二.具体代码实现 一.哈夫曼编码原理 哈夫曼编码&#xff08;Huffman Coding&#xff09;是一种用于数据压缩的编码方法&#xff0c;它通过给出不同的数据符号分配不同长度的编码&#xff0c;使得出现频率高的符号具有较短的编码&a…