【正则表达式】1、元字符的认识与分类

1、元字符的概念

        正则表达式的常见功能,分别是校验数据的有效性、查找符合要求的文本以及对文本进行切割和替换等操作。

        我想你一定在办公软件,比如 Word、Excel 中用过这个功能。你可以使用查找功能快速定位关注的内容,然后使用替换,批量更改这些内容。

        让我们再回过头看看正则表达式。正则表达式,简单地说就是描述字符串的规则。在正则中,普通字符表示的还是原来的意思,比如字符 a,它可以匹配“Hanmeimei is a girl”中的 H 之后的 a,也可以匹配 is 之后的 a,这个和我们日常见到的普通的字符串查找是一样的。

正则表达验证

        但除此之外,正则还可以做到普通的查找替换做不到的功能,它真正的强大之处就在于可以查找符合某个规则的文本。

        举个例子,假如你想查找文本中的所有数字,如果不会正则,可能需要手动敲数字,从 0 到 9 这样操作 10 次,一个个去查找,很麻烦。但如果用正则的话就方便很多了,我们直接使用 \d 就可以表示 0-9 这 10 个数字中的任意一个,如下图所示。

        如果我们在后面再加上量词,就可以表示单个的数字出现了几次。比如 \d{11} 表示单个数字出现 11 次,即 11 位数字,如果文本中只有姓名和手机号,我们就可以利用这个查找出文本中的手机号了,如下图所示。

        那么到这里,你有没有发现正则的不同呢?像查找数字一样,在正则中,我们不需要像往常一样输入一个确定的内容,只需要敲入特殊的符号就可以帮我们完成查找和替换,像上面案例中提到的 \d 和 {11},在正则中有一个专门的名称——元字符(Metacharacter)。

        所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,元字符是构成正则表达式的基本元件。正则就是由一系列的元字符组成的,但是,因为元字符很基础,又比较多,所以很多人看见正则就头疼。那么今天,我就通过分类的方式,教你理解并且巧妙地记忆、使用元字符。

2、元字符的分类

        首先,我可以把元字符大致分成这几类:表示单个特殊字符的,表示空白符的,表示某个范围的,表示次数的量词,另外还有表示断言的,我们可以把它理解成边界限定。

2.1、特殊单字符

        首先,我们来看下表示特殊单个字符的元字符,比如英文的点(.)表示换行以外的任意单个字符,\d 表示任意单个数字,\w 表示任意单个数字或字母或下划线,\s 表示任意单个空白符。另外,还有与之对应的三个 \D、\W 和 \S,分别表示着和原来相反的意思。

        现在我们来看一下测试,我把常见数字,字母,部分标点符号作为文本,用 \d 去查找,可以看到只能匹配上 10 个数字。这是元字符 \d 测试用例的链接,你不妨测试一下。

2.2、空白符

        除了特殊单字符外,你在处理文本的时候肯定还会遇到空格、换行等空白符。其实在写代码的时候也会经常用到,换行符 \n,TAB 制表符 \t 等。

        有编程经验的程序员肯定都知道,不同的系统在每行文本结束位置默认的“换行”会有区别。比如在 Windows 里是 \r\n,在 Linux 和 MacOS 中是 \n。

        在正则中,也是类似于 \n 或 \r 等方式来表示空白符号,只要记住它们就行了。平时使用正则,大部分场景使用 \s 就可以满足需求,\s 代表任意单个空白符号。

        我们可以看到, \s 能匹配上各种空白符号,也可以匹配上空格。换行有专门的表示方式,在正则中,空格就是用普通的字符英文的空格来表示。

2.3、量词

        刚刚我们说到的“基础”的元字符也好,“空白符”也好,它们都只能匹配单个字符,比如\d 只能匹配一个数字。但更多时候,我们需要匹配单个字符,或者某个部分“重复 N 次”“至少出现一次”“最多出现三次”等等这样的字符,这个时候该怎么办呢?这就需要用到表示量词的元字符了。

        在正则中,英文的星号(*)代表出现 0 到多次,加号(+)代表 1 到多次,问号(?)代表 0 到 1 次,{m,n}代表 m 到 n 次。

        比如,在文本中“颜色”这个单词,可能是带有 u 的 colour,也可能是不带 u 的 color,我们使用 colou?r 就可以表示两种情况了。在真实的业务场景中,比如某个日志需要添加了一个 user 字段,但在旧日志中,这个是没有的,那么这时候可以使用问号来表示出现 0 次或 1 次,这样就可以表示 user 字段存在和不存在两种情况。

        下面这段文本由三行数字组成,当我们使用 \d+ 时,能匹配上 3 个,但使用 \d* 时能匹配上 6 个,详细匹配结果可以参考下面的图片:

2.4、范围

        学习了量词,我们就可以用 \d{11} 去匹配所有手机号,但同时也要明白,这个范围比较大,有一些不是手机号的数字也会被匹配上,比如 11 个 0,那么我们就需要在一个特殊的范围里找符合要求的数字。

        再比如,我们要找出所有元音字母 aeiou 的个数,这又要如何实现呢?在正则表达式中,表示范围的元字符可以轻松帮我们搞定这样的问题。在正则表达式中,表示范围的符号有四个分类,如下图所示。

        首先是管道符号,我们用它来隔开多个正则,表示满足其中任意一个就行,比如 ab|bc 能匹配上 ab,也能匹配上 bc,在正则有多种情况时,这个非常有用。

        中括号[]代表多选一,可以表示里面的任意单个字符,所以任意元音字母可以用 [aeiou] 来表示。另外,中括号中,我们还可以用中划线表示范围,比如 [a-z] 可以表示所有小写字母。如果中括号第一个是脱字符(^),那么就表示非,表达的是不能是里面的任何单个元素。

        比如某个资源可能以 http:// 开头,或者 https:// 开头,也可能以 ftp:// 开头,那么资源的协议部分,我们可以使用 (https?|ftp):// 来表示。

2.5、思考题

这里给出一些手机号的组成规则:

第 1 位固定为数字 1;

第 2 位可能是 3,4,5,6,7,8,9;

第 3 位到第 11 位我们认为可能是 0-9 任意数字。

答案:

  • 1[3-9]\d{9}
  • 1[3-9][0-9]{9}
  • 1[3-9]{1}\d{9}

3、量词的相关模式

        上文说到量词的6种元字符中,我们可以用 {m,n} 来表示 (*)(+)(?) 这 3 种元字符:

        表示量词的星号(*)和 加号(+)可能没你想象的那么简单,我用一个例子给你讲解一下。我们先看一下加号(+),使用 a+ 在 aaabb 中查找,可以看到只有一个输出结果:

        加号应该很容易理解,我们再使用 a* 在 aaabb 这个字符串中进行查找,这次我们看到可以找到 4 个匹配结果。

        但这一次的结果匹配到了三次空字符串。为什么会匹配到空字符串呢?因为星号(*)代表 0 到多次,匹配 0 次就是空字符串。到这里,你可能会有疑问,如果这样,aaa 部分应该也有空字符串,为什么没匹配上呢?

        这就引入了我们今天要讲的话题,贪婪与非贪婪模式。这两种模式都必须满足匹配次数的要求才能匹配上。贪婪模式,简单说就是尽可能进行最长匹配。非贪婪模式呢,则会尽可能进行最短匹配。正是这两种模式产生了不同的匹配结果。

3.1、贪婪匹配(Greedy)

        首先,我们来看一下贪婪匹配。在正则中,表示次数的量词默认是贪婪的,在贪婪模式下,会尝试尽可能最大长度去匹配。首先,我们来看一下在字符串 aaabb 中使用正则 a* 的匹配过程。

        a* 在匹配开头的 a 时,会尝试尽量匹配更多的 a,直到第一个字母 b 不满足要求为止,匹配上三个 a,后面每次匹配时都得到了空字符串。

        相信看到这里你也发现了,贪婪模式的特点就是尽可能进行最大长度匹配。所以要不要使用贪婪模式是根据需求场景来定的。如果我们想尽可能最短匹配呢?那就要用到非贪婪匹配模式了。

3.2、非贪婪匹配(Lazy)

        那么如何将贪婪模式变成非贪婪模式呢?我们可以在量词后面加上英文的问号 (?),正则就变成了 a*?。此时的匹配结果如下:

        这一次我们可以看到,这次匹配到的结果都是单个的 a,就连每个 a 左边的空字符串也匹配上了。到这里你可能就明白了,非贪婪模式会尽可能短地去匹配,我把这两者之间的区别写到了下面这张图中。

        为了让你加深理解,我们再来看一个示例,这一次让我们查找一下引号中的单词。

        从下面这个示例中,我们可以很容易看出两者对比上的差异。左右的文本是一样的,其中有两对双引号。不同之处在于,左边的示例中,不加问号时正则是贪婪匹配,匹配上了从第一个引号到最后一个引号之间的所有内容;而右边的图是非贪婪匹配,找到了符合要求的结果。

3.3、独占模式(Possessive)

        不管是贪婪模式,还是非贪婪模式,都需要发生回溯才能完成相应的功能。但是在一些场景下,我们不需要回溯,匹配不上返回失败就好了,因此正则中还有另外一种模式,独占模式,它类似贪婪匹配,但匹配过程不会发生回溯,因此在一些场合下性能会更好。

        你可能会问,那什么是回溯呢?我们来看一些例子,例如下面的正则:

regex = “xy{1,3}z”

text = “xyyz”

        在匹配时,y{1,3}会尽可能长地去匹配,当匹配完 xyy 后,由于 y 要尽可能匹配最长,即三个,但字符串中后面是个 z 就会导致匹配不上,这时候正则就会向前回溯,吐出当前字符 z,接着用正则中的 z 去匹配。

如果我们把这个正则改成非贪婪模式,如下:

regex = “xy{1,3}?z”

text = “xyyz”

        由于 y{1,3}? 代表匹配 1 到 3 个 y,尽可能少地匹配。匹配上一个 y 之后,也就是在匹配上 text 中的 xy 后,正则会使用 z 和 text 中的 xy 后面的 y 比较,发现正则 z 和 y 不匹配,这时正则就会向前回溯,重新查看 y 匹配两个的情况,匹配上正则中的 xyy,然后再用 z 去匹配 text 中的 z,匹配成功。

        了解了回溯,我们再看下独占模式。独占模式和贪婪模式很像,独占模式会尽可能多地去匹配,如果匹配失败就结束,不会进行回溯,这样的话就比较节省时间。具体的方法就是在量词后面加上加号(+)。

regex = “xy{1,3}+yz”

text = “xyyz”

        如果你用 a{1,3}+ab 去匹配 aaab 字符串,a{1,3}+ 会把前面三个 a 都用掉,并且不会回溯,这样字符串中内容只剩下 b 了,导致正则中加号后面的 a 匹配不到符合要求的内容,匹配失败。如果是贪婪模式 a{1,3} 或非贪婪模式 a{1,3}? 都可以匹配上。

3.4、正则回溯的风险

        这里我们挑选一个比较出名的,是阿里技术微信公众号上的发文。Lazada 卖家中心店铺名检验规则比较复杂,名称中可以出现下面这些组合:

  1. 英文字母大小写;
  2. 数字;
  3. 越南文;
  4. 一些特殊字符,如“&”,“-”,“_”等。

负责开发的小伙伴在开发过程中使用了正则来实现店铺名称校验,如下所示:

^([A-Za-z0-9._()&'\- ]|[aAàÀảẢãÃáÁạẠăĂằẰẳẲẵẴắẮặẶâÂầẦẩẨẫẪấẤậẬbBcCdDđĐeEèÈẻẺẽẼéÉẹẸêÊềỀểỂễỄếẾệỆfFgGhHiIìÌỉỈĩĨíÍịỊjJkKlLmMnNoOòÒỏỎõÕóÓọỌôÔồỒổỔỗỖốỐộỘơƠờỜởỞỡỠớỚợỢpPqQrRsStTuUùÙủỦũŨúÚụỤưƯừỪửỬữỮứỨựỰvVwWxXyYỳỲỷỶỹỸýÝỵỴzZ])+$

        这个正则比较长,但很好理解,中括号里面代表多选一,我们简化一下,就成下面这样:

^([符合要求的组成1]|[符合要求的组成2])+$ 

        脱字符(^)代表以这个正则开头,美元符号($)代表以正则结尾,我们后面会专门进行讲解。这里可以先理解成整个店铺名称要能匹配上正则,即起到验证的作用。

        你需要留意的是,正则中有个加号(+),表示前面的内容出现一到多次,进行贪婪匹配,这样会导致大量回溯,占用大量 CPU 资源,引发线上问题,我们只需要将贪婪模式改成独占模式就可以解决这个问题。

        仔细再看一下 这个正则,你会发现 “组成 1” 和 “组成 2” 部分中,A-Za-z 英文字母在两个集合里面重复出现了,这会导致回溯后的重复判断。这里要强调一下,并不是说有回溯就会导致问题,你应该尽量减少回溯后的计算量。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

leetcode-最长公共子序列(二)-103

题目要求 思路 step 1:优先检查特殊情况。 step 2:获取最长公共子序列的长度可以使用动态规划,我们以dp[i][j]dp[i][j]dp[i][j]表示在s1中以iii结尾,s2中以jjj结尾的字符串的最长公共子序列长度。 step 3:遍历两个字…

视频号小店从开店到爆单,最详细的攻略教学,来了!

大家好,我是喷火龙 视频号小店从推出到现在一直备受关注,我的团队已经入局视频号小店一年多了, 可以说,新手做视频号小店采用无货源模式和达人带货的玩法依旧是最合适的。 虽然说这个模式和玩法很多人之前都接触过,…

精准追踪,高效分析——Xinstall应用数据分析平台

在当前的移动互联网时代,App应用的数量与日俱增,如何从这些应用中脱颖而出,成为开发者和广告主们亟待解决的问题。而在这个问题中,数据无疑是一把关键的钥匙。今天,我们要介绍的就是国内专业的App全渠道统计服务商——…

普中STM32F103ZET6开发板让DS0和DS1两个LED同时亮

欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一.前言 二.代码 三.运行效果 一.前言 在这套stm32教程中,只教学了如何亮DS0,而没有教学如何亮DS1。 二.代码 main.c #include "stm32f10x.h"void Syst

Linux下Redis下载及安装教程(实测有效)

一、配置gcc 由于Redis是基于c语言编写的需要安装依赖,需要安装gcc,在Linux系统里需要存在C语言的编译环境,一般的Linux系统安装的时候会自动安装,由于我是最小安装模式,所以我需要自己再另外安装一下。 判断系统是否安装gcc&…

2024年Java程序员的职业发展路径

程序员的职业路径是非常清晰的,但是现实情况下,很多人卡在了高级开发就再也上不去,直到遇到职业发展的危机,比如: 35岁大龄程序员找工作难,国内很多大型互联网公司在招聘要求上,会限制35岁这个年…

PuLID: 图像背景、光线、风格等均保持高度一致图像生成工具,附本地一键包

PuLID是一种无需调优的ID定制方法。PuLID保持了高的ID保真度,同时有效地减少了对原始模型行为的干扰。 只需要提供一张照片,就可以生成高还原度的各种风格的图像。 使用方法:解压一键包,双击一键启动 点击ID图像(主…

李国武:确保FMEA实现预期质量目标的方法有哪些?

在现代制造业中,FMEA(失效模式与影响分析)已经成为一项至关重要的质量管理工具。它通过对产品或过程进行系统的分析,识别潜在的失效模式,评估其影响,并制定相应的预防措施,从而确保产品或过程的…

Nginx 代理 MySQL 实现通过域名连接数据库

文章目录 Nginx 模块介绍Stream 模块配置远程连接 MySQLDataGrip 连接 MySQL Nginx 安装这里不做介绍。域名默认已经解析到服务器公网IP。 Nginx 模块介绍 HTTP 模块: HTTP模块提供了处理HTTP请求的功能,包括反向代理、负载均衡、缓存、HTTP代理等。 例…

Docker下载镜像出现“missing signature key”如何解决?

“missing signature key” 通常与 Docker 配置有关,具体是 Docker 试图验证镜像的签名但未能找到相应的密钥。这种情况可能发生在启用了 Docker Content Trust (DCT) 的环境中,DCT 是一种安全功能,要求所有镜像必须有签名才能拉取。 原因 …

资料同化 | 搭建docker环境-1

Community Gridpoint Statistical Interpolation (GSI) system DTC 是一个分布式设施,NWP 社区可以在这里测试和评估用于研究和操作的新模型和技术。 DTC的目标包括: 链接研究和操作社区 研究成果转化为实际操作的速度 加快改善天气预报 开发和测试有…

独享静态IP:跨境网络新助手

在数字化浪潮席卷全球的今天,互联网已成为人们生活中不可或缺的一部分。而在这个由数据和信息构成的虚拟世界里,IP地址作为每一个网络设备的独特标识,其重要性不言而喻。特别是独享静态IP,它不仅为用户提供了更加稳定、安全的网络…

在虚机VirtualBox7.0.8安装Androidx86_64系统详细步骤要点

最近需要用到安卓系统蓝牙功能做测试,就选择了Virtualboxandroidx86方案,先把系统安装好,后面看是否可以比较好的完成蓝牙功能测试。如果可以的话,我会再发文分享下的,敬请期待。 1.准备材料 (1&#xff…

[数据集][目标检测]交通灯检测数据集VOC+YOLO格式2600张1类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2600 标注数量(xml文件个数):2600 标注数量(txt文件个数):2600 标注…

食家巷传统面点积极响应中国品牌日,打造国货潮牌

2024 年中国品牌日活动以“中国品牌,世界共享;国货潮牌,品筑未来”为主题,旨在推动中国品牌的发展和国际化,展示国货潮牌的魅力和创新。食家巷传统面点品牌积极响应活动号召,以实际行动助力中国品牌的崛起。…

PyQt5编写的一个简易图像处理软件

文章目录 1. 简介2. 准备工作3. 主界面设计4. 功能构建5. 总结 1. 简介 通过编写简易图像处理软件,你可以学习如何使用 PyQt5 构建用户界面,以及如何与用户交互。同时,你还可以学习图像处理技术,如图像读取、傅里叶变换、滤波、增…

ThinkPad T480(20L5,20L6)原装出厂Win10系统镜像下载

lenovo联想ThinkPad系列 T480笔记本电脑20L5、20L6原厂OEM预装Windows10系统,恢复开箱状态一模一样,带有恢复重置功能 链接:https://pan.baidu.com/s/1NqqBKC_v2mPDs2qTxsYvxA?pwdeivm 提取码:eivm 原装出厂系统自带所有驱动…

【机器学习】AI在空战决策中的崛起:从理论到实践的跨越

AI在空战决策中的崛起:从理论到实践的跨越 一、引言二、AI技术的崛起与空军决策技术层面作战结构 三、AI在空战决策中的前景展望四、结语 一、引言 随着科技的不断进步,现代战争已经步入了一个全新的时代。其中,空战作为战争的重要组成部分&a…

PG pageinspect使用与块空间清理学习

1.创建有时候会报错 ERROR: could not open extension control file "/usr/local/pgsql/share/extension/pageinspect.control": No such file or directory 解决方案: 2.使用 PostgreSQL中,对于每一行数据(称为一个tuple&#…

caj文件是什么?caj是什么文件?考研学生赶紧收藏!

在学术研究的广阔领域中,尤其是对于那些致力于深入研究、不断拓宽知识边界的考研学子们来说,了解并掌握各种学术资源的获取与利用方法显得尤为重要。其中,CAJ文件作为一种常见的学术文件格式,其重要性和使用频率不容忽视。那么&am…