正则表达式 详解,10分钟学会

大家好,欢迎来到停止重构的频道。

本期我们讨论正则表达式

正则表达式是一种用于匹配和操作文本的工具,常用于文本查找、文本替换、校验文本格式等场景。

正则表达式不仅是写代码时才会使用,在平常使用的很多文本编辑软件,都是支持正则表达式搜索或替换的。

如vs code、notepad++、word、excel等,其中,word、excel中的正则表达式语法存在一些差异。

​我们将从以下几点展开讨论:

1、正则表达式介绍与应用

2、正则表达式语法详解

3、记不住语法的解决方案

1、正则表达式 介绍 & 应用

首先是正则表达式的介绍与应用。

正则表达式是一种用于匹配和操作文本的工具,可以用于文本查找、文本替换、文本格式校验等场景​。

正则表达式本身也是一段文本,或者说是一条字符串。

如图所示,示例1的正则表达式可以检查字符串是否符合邮箱的格式,示例2的正则表达式可以查找所有a开头的单词。

在程序开发中,正则表达式可用于字符串或文本的查找替换格式校验,以下Python为例。

示例1为查找a开头的所有单词。​

示例2为替换手机号中间数字为*号。

​示例3为校验字符串是否符合邮箱格式。

这里顺便一提,一般数据库,如MySQL,都是支持正则表达式查询的。

正则表达式可以通过简单的一条字符串,告诉程序应该执行什么样的文本匹配和操作。

如果是正常写代码的话,将是一大段代码,且维护性特别差。

不过,正则表达式的处理性能一般都不会太高,且越复杂的正则表达式处理起来越慢。

但是一般的应用开发是不需要考虑这个性能的。

​在我们开源的代码生成器Christmas中,也大量使用正则表达式,感兴趣的小伙伴可以下载翻看。

在日常办公中,很多文本处理软件也是支持正则表达式检索或替换的。

如word,在搜索框输入一条正则表达式,即可搜索出所有手机号。

2、语法:大纲

接下来详细讲解正则表达式的语法。

这里需要特别说明的是,不同正则表达式解析引擎可能有细微的语法差别,我们下面介绍的是最为通用的正则表达式标准。

​正则表达式说白了就是高级版关键字搜索

对比普通的关键字搜索,正则表达式加入了很多具有特殊意义的元字符,通过加入这些元字符,即可实现灵活性更高的模糊匹配​。

理论上只要记住这些元字符,就几乎等于掌握了正则表达式。

但是元字符总共有几十个且很难记忆,所以通过列举的方式介绍每个元字符,并不是很好的介绍方法。

​我们尝试将正则表达式的语法结构化,将正则表达式语法分为:普通字符、字符集合、限定符、定位符、子表达式、省略符、修饰符。

2-1、语法:普通字符

首先是普通字符

普通字符可以理解为明确的关键字,主要包括文字字符、符号​。

文字字符指的是英文字母、数字、中文字这些,文字字符在正则表达式中直接写就可以了。

如需要匹配get这个单词,正则表达式则直接写为get。

而符号,像%、_这些一般也是直接写就可以了。如需要匹配_get,正则表达式也是_get。

但是一些符号由于在正则表达式中有特殊含义,如果需要匹配这些符号,则需要\转义。

图中是需要转义的特殊符号,如需要匹配get*,正则表达式是get\*。

​普通字符除了文字字符、符号以外,还有一些不太常用的非打印字符、16进制、8进制、Unicode编码字符等。

这些都不需要记住,用到的时候再查就行。

2-2、语法:字符集合

​​接下来是字符集合。

字符集合是单个字符的值范围,只要符合这个范围的字符都算是匹配成功。字符集合包含在一对[]之间,[]内,每一个字符都是允许匹配的值。

字符集合适合匹配多个关键字,且这多个关键字中只有个别字符存在差异的情况​。

如需匹配文本中的get、got,这两个关键字只有中间的字符存在差异,所以采用字符集合是合理的。

​​这里需要特别说明的是,字符集合是单个字符的值范围。

如需匹配文本中的get、goat这两个单词,由于这两个单词的差异不仅仅在一个字符上,所以不能采用字符集合。

​字符集合中,为了简化连续字符,可以使用-标识连续字符的范围。

如需匹配文本中的gat、gbt、gct,正则表达式如图所示。

如果希望字符集合为排除在外的范围,则可以在字符集合的最开端添加^号。

2-3、语法:限定符

接下来是限定符。限定符是为了给前一个字符追加出现次数范围,常用的限定符为*号、+号、?号。

*号表示要求前一个字符出现0次或多次。

+号表示要求前一个字符出现1次或多次。

?号表示要求前一个字符出现0次或1次。

​如需要匹配文本中的god、good、goood,由于都是以g开头、d结尾,且中间包含1个或以上个o字符,则正则表达式为go+d。

​如果以上常用的限定符不能满足需求,如指定3次、3-6次等。可以使用{}标注具体次数。

当限定符前面的字符是一个模糊的匹配范围,如一个字符集合,则会发生贪婪匹配的问题。

默认情况下,正则表达式会匹配到尽量多的字符,这也称为贪婪匹配。

如示例1中,会匹配文本中的gadxxgod一长串字符串(贪婪匹配)。

​但如果我们不希望匹配这个长字符串,而是其中的gad、god这两个字符串。

则应该如示例2中,在示例一的限定符后追加?号即可实现非贪婪匹配,就可以匹配到gad、god这两个字符串。

2-4、语法:定位符

接下来是定位符,定位符是标记匹配位置而存在的

定位符只有四个,整个字符串的开端、整个字符串的末尾、单词边界、非单词边界。

​​以校验字符串是否为11位手机号为例,加入定位符更有利于精细匹配。

2-5、语法:子表达式

接下来是子表达式,子表达式是内嵌的子正则表达式。

子表达式写在一对()中间,子表达式与正则表达式的语法相同,子表达式内可以再内嵌子表达式。

​那子表达式有什么用呢?

子表达式可以看作是一个整体,如示例所示,当子表达式后添加限定符后,则可以匹配文本中连续的got字符串。

子表达式也可以作为多种情况的匹配范围,子表达式中用|分割多个子表达式,以表示多种情况。

如需要匹配文本中的get、goat两个字符串,正则表达式如图所示。

子表达式也可以标记子匹配项,如需要匹配文本中AABB形式的字符串,示例中的\1表示与第1个子匹配项相同的内容,\2表示与第2个子匹配项相同的内容。

这里值得一提的是,在正则表达式标准中,每个子表达式的匹配结果会单独存储。

​如果子表达式的匹配结果不需要存储,可以在子表达式前添加标记,不过这个在日常使用中不太常用。

​另外,子表达式也可以作为预查匹配项,预查匹配项可以理解为自定义的定位符​。因为定位符只有四个,但是实际应用中,是远远不够的。

如图中示例,预查匹配项可以指定目标结果的前或后的特征,子表达式作为预查匹配项时,需要根据4种不同的预查匹配模式,添加对应的标识。

2-6、语法:省略符

通过以上语法,其实已经可以写出全部功能的正则表达式。但是一些局部未免有些啰嗦,所以出现了省略符。

省略符是一些为了简化正则表达式而存在的元字符,一般以\开头,如示例中的\d即可代表所有数字的字符集合。

常用的省略符如图所示,但是省略符仅仅是为了简化正则表达式而存在的,每个省略符都有对应的替代方案,所以省略符不必强行记忆

2-7、语法:修饰符

最后是修饰符,严格意义上讲,修饰符并不是正则表达式的一部分。

修饰符是指定匹配策略的,如不区分大小写、多行匹配等,所以相同正则表达式,在指定不同修饰符情况下,匹配的结果会有所区别。

修饰符一般是4个,且修饰符可以叠加使用,但是某些正则表达式代码库可能存在不同的匹配策略,可能存在多于4个修饰符的设置。

这里需要特别说明的是,有些软件虽然支持正则表达式搜索,但不一定开放修饰符的设置。

3、记不住语法的解决方案

​在以上语法讲解中,我们已经尽量结构化了,但是仍然有很多难以记忆的标记或语法。

除非是每天都使用正则表达式,否则是不可能随随便便就写出一条准确无误的正则表达式的。

以我个人为例,​虽然使用正则表达式很多年,但是一到写正则表达式的时候,还是需要翻看手册。

所以记不住语法是正常的

平常写正则表达式时,可以先在在线网站测试一下。

当然,如果你有一个AI助手,最好的方法是直接问AI,只要不是特别复杂或特殊的,AI助手一般都能直接给出答案,AI助手甚至能标注各个片段的作用。

总结

最后,正则表达式非常实用也足够流行,在非常多的文本处理软件中,都支持正则表达式​。大多数编程语言的标准库也包含正则表达式的支持。

但是在我们看来,正则表达式的某些元字符或标记的设计并不友好,注定是难以记忆的。

当然很多开源项目也尝试对正则表达式的语法进行改进,如google的re2,但是大多数人并不会选用。

毕竟正则表达式虽然很常用,但对于大多数人来说,也没有到天天都需要使用的程度,更何况现在有比搜索引擎更高效的AI助手呢。

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

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

相关文章

关于Python里xlwings库对Excel表格的操作(二十五)

这篇小笔记主要记录如何【如何使用xlwings库的“Chart”类创建一个新图表】。 前面的小笔记已整理成目录,可点链接去目录寻找所需更方便。 【目录部分内容如下】【点击此处可进入目录】 (1)如何安装导入xlwings库; (2…

案例分享:Qt多国语言输入法软键盘

若该文为原创文章,转载请注明出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/135346374 红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…

aspose通过开始和结束位置关键词截取word另存为新文件

关键词匹配实体类: Data EqualsAndHashCode(callSuper false) public class TextConfig implements Serializable {private static final long serialVersionUID 1L;/*** 开始关键词,多个逗号分隔*/private String textStart ;/*** 结束关键词&#x…

【操作系统xv6】学习记录4 -CPU上下文:进程上下文、线程上下文、中断上下文

什么是cpu上下文 CPU 寄存器和程序计数器就是 CPU 上下文,因为它们都是 CPU 在运行任何任务前,必须的依赖环境。 什么是 CPU 上下文切换 先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来,然后…

Flutter+Go_Router+Fluent_Ui仿阿里网盘桌面软件开发跨平台实战-买就送仿小米app开发

Flutter是谷歌公司开发的一款开源、免费的UI框架,可以让我们快速的在Android和iOS上构建高质量App。它最大的特点就是跨平台、以及高性能。 目前 Flutter 已经支持 iOS、Android、Web、Windows、macOS、Linux 的跨平台开发。 Flutter官方介绍,目前Flutte…

ubuntu系统没有网络图标的解决办法

参考文章:https://blog.csdn.net/qq_56922632/article/details/132309643 1. 执行关闭网络服务的命令,关闭网络服务sudo service NetworkManager stop2. 删除网络的状态文件sudo rm /var/lib/NetworkManager/NetworkManager.state3. 修改网络的配置文件sudo vi /etc…

冒泡排序-排序算法

前言 如果有6个人站成一排,要将他们按从矮到高的顺序排列。你可能有多种方式来完成。但是如果其中有一个人特别高,比他身边的人高,在队伍中特别明显,你可以轻易看出那个最高的需要和身边的人交换位置,这是冒泡排序的核…

二叉树的前序遍历 、二叉树的最大深度、平衡二叉树、二叉树遍历【LeetCode刷题日志】

目录 一、二叉树的前序遍历 方法一:全局变量记录节点个数 方法二:传址调用记录节点个数 二、二叉树的最大深度 三、平衡二叉树 四、二叉树遍历 一、二叉树的前序遍历 方法一:全局变量记录节点个数 计算树的节点数: 函数TreeSize用于…

案例086:基于微信小程序的影院选座系统

文末获取源码 开发语言:Java 框架:SSM JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder X 小程序…

履机乘变,轻舟便楫:源启分布式PaaS深度赋能企业级技术平台建设

导语 源启分布式PaaS平台围绕应用视角为用户提供应用运行的全生命周期管控能力,提供注册中心、服务路由、网关、服务治理等中间件技术支持,实现应用之间的联通,解决客户多厂商产品不兼容、产品组合不可选择、孤岛效应等问题,满足…

ros2 基础学习12 分布式通信

智能机器人的功能繁多,全都放在一个计算机里,经常会遇到计算能力不够、处理出现卡顿等情况,如果可以将这些任务拆解,分配到多个计算机中运行岂不是可以减轻压力? 这就是分布式系统,可以实现多计算平台上的任…

android开发百度地图api实现定位图标随手机方向转动

该功能的实现依赖于手机中的传感器元件如陀螺仪、加速度计等,具体开发详见android的官方开发文档: 传感器概览 | Android 开发者 | Android Developershttps://developer.android.com/guide/topics/sensors/sensors_overview?hlzh-cn要自定义一个传…

Hive学习(13)lag和lead函数取偏移量

hive里面lag函数 在数据处理和分析中,窗口函数是一种重要的技术,用于在数据集中执行聚合和分析操作。Hive作为一种大数据处理框架,也提供了窗口函数的支持。在Hive中,Lag函数是一种常用的窗口函数,可以用于计算前一行…

《动手学深度学习》学习笔记 第6章 卷积神经网络

本系列为《动手学深度学习》学习笔记 书籍链接:动手学深度学习 笔记是从第四章开始,前面三章为基础知道,有需要的可以自己去看看 关于本系列笔记: 书里为了让读者更好的理解,有大篇幅的描述性的文字,内容很…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-9PID控制器

本文仅供学习使用 本文参考: B站:DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-9PID控制器) P —— Proportional I —— Integral D —— Derivative 当前误差/过去误差/误差的变化趋势 K p ⋅ e K_{\mathrm{p}}\cdot e Kp​⋅e:比…

golang并发编程-channel

在golang 并发编程里,经常会听到一句话:不要通过共享内存进行通信,通过通信来共享内存。下面我们会介绍下channel, 通过源码的方式去了解channel是怎么工作的。 基本结构 流程图 代码解读 type hchan struct {qcount uint // …

Qt(三):udp组播的发送与接收

1. 创建UDP套接字 使用QUdpSocket类创建一个UDP套接字。 udpSendnew QUdpSocket(this);udpRecenew QUdpSocket(this); 2. 绑定套接字 绑定套接字到一个本地地址和端口。可以使用bind()函数来完成。 如果要在组播中发送数据,可以将套接字绑定到一个通配符地址&#…

uniapp中uview组件丰富的Code 验证码输入框的使用方法

目录 基本使用 #自定义提示语 #保持倒计时 API #Props #Methods #Event 基本使用 通过ref获取组件对象,再执行后面的操作,见下方示例。 通过seconds设置需要倒计的秒数(默认60)通过ref调用组件内部的start方法,开始倒计时通过监听cha…

智慧旅游手机APP开发解决方案

我国的旅游市场已经逐渐地走向饱和,想要发展,就必须要寻求新的发展模式。本项目就是抓住贵州的交通飞速发展的契机,以高速为主线,高速周边的景点、酒店为依托,高速维修为辅线,借助今天得到广泛应用的智能移…

SpringBoot整合多数据源,并支持动态新增与切换

SpringBoot整合多数据源,并支持动态新增与切换 一、概述 在项目的开发过程中,遇到了需要从数据库中动态查询新的数据源信息并切换到该数据源做相应的查询操作,这样就产生了动态切换数据源的场景。为了能够灵活地指定具体的数据库&#xff0…