当前位置: 首页 > news >正文

正则表达式 详解,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助手呢。

相关文章:

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

大家好,欢迎来到停止重构的频道。 本期我们讨论正则表达式。 正则表达式是一种用于匹配和操作文本的工具,常用于文本查找、文本替换、校验文本格式等场景。 正则表达式不仅是写代码时才会使用,在平常使用的很多文本编辑软件,都…...

【排序算法】归并排序与快速排序:深入解析与比较

文章目录 1. 引言2. 归并排序(Merge Sort)3. 快速排序(Quick Sort)4. 归并排序与快速排序的比较5. 结论 1. 引言 排序算法是计算机科学中最基本且至关重要的概念之一。它们不仅是理解更复杂算法和数据结构的基石,而且…...

万字长文谈自动驾驶bev感知(一)

文章目录 prologuepaper listcamera bev :1. Lift, Splat, Shoot: Encoding Images from Arbitrary Camera Rigs by Implicitly Unprojecting to 3D2. M2BEV: Multi-Camera Joint 3D Detection and Segmentation with Unified Birds-Eye View Representation3. BEVDet: High-Pe…...

cfa一级考生复习经验分享系列(十七)

考场经验: 1.本人在Prometric广州考试中心,提前一天在附近住下,地方比较好找,到了百汇广场北门,进去就可以看见电梯直达10楼。进去之后需要现场检查行程卡和健康码,然后会问最近你有没有发烧咳嗽等问题&…...

机器人活动区域 - 华为OD统一考试

OD统一考试 题解: Java / Python / C++ 题目描述 现有一个机器人,可放置于 M x N 的网格中任意位置,每个网格包含一个非负整数编号,当相邻网格的数字编号差值的绝对值小于等于 1 时机器人可以在网格间移动。 问题: 求机器人可活动的最大范围对应的网格点数目。 说明: 网格…...

三、HTML元素

一、HTML元素 HTML 文档由 HTML 元素定义。 *开始标签常被称为起始标签(opening tag),结束标签常称为闭合标签(closing tag)。 二、HTML 元素语法 HTML 元素以开始标签起始。HTML 元素以结束标签终止。元素的内容是…...

置顶> 个人学习记录一览

个人学习记录一览表 写个说明   知识学的好,不如笔记记得好,知识点的遗忘在所难免,这里记录我个人的学习过程,以备后面二次学习使用。 Linux 操作系统 Linux 操作系统 001-介绍 Linux 操作系统 002-VMware Workstation的相关操…...

c++重载操作符

支持重载操作符是c的一个特性,先不管好不好用,这起码能让它看起来比其他语言NB很多,但真正了解重载操作符后,就会发现这个特性...就这?本文分两个部分 重载操作符简介和使用——适用新手重载操作符的原理和sao操作——…...

C# 如何读取Excel文件

当处理Excel文件时,从中读取数据是一个常见的需求。通过读取Excel数据,可以获取电子表格中包含的信息,并在其他应用程序或编程环境中使用这些数据进行进一步的处理和分析。本文将分享一个使用免费库来实现C#中读取Excel数据的方法。具体如下&…...

Vue2面试题:说一下对vuex的理解?

五种状态: state: 存储公共数据 this.$store.state mutations:同步操作,改变store的数据 this.$store.commit() actions: 异步操作,让mutations中的方法能在异步操作中起作用 this.$store.dispatch() getters: 计算属性 th…...

elasticsearch系列五:集群的备份与恢复

概述 前几篇咱们讲了es的语法、存储的优化、常规运维等等,今天咱们看下如何备份数据和恢复数据。 在传统的关系型数据库中我们有多种备份方式,常见有热备、冷备、全量定时增量备份、通过开发程序备份等等,其实在es中是一样的。 官方建议采用s…...

【Elasticsearch源码】 分片恢复分析

带着疑问学源码,第七篇:Elasticsearch 分片恢复分析 代码分析基于:https://github.com/jiankunking/elasticsearch Elasticsearch 8.0.0-SNAPSHOT 目的 在看源码之前先梳理一下,自己对于分片恢复的疑问点: 网上对于E…...

elasticsearch如何操作索引库里面的文档

上节介绍了索引库的CRUD,接下来操作索引库里面的文档 目录 一、添加文档 二、查询文档 三、删除文档 四、修改文档 一、添加文档 新增文档的DSL语法如下 POST /索引库名/_doc/文档id(不加id,es会自动生成) { "字段1":"值1", "字段2&q…...

opencv期末练习题(2)附带解析

图像插值与缩放 %matplotlib inline import cv2 import matplotlib.pyplot as plt def imshow(img,grayFalse,bgr_modeFalse):if gray:img cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)plt.imshow(img,cmap"gray")else:if not bgr_mode:img cv2.cvtColor(img,cv2.COLOR_B…...

【Mybatis】深入学习MyBatis:高级特性与Spring整合

🍎个人博客:个人主页 🏆个人专栏: Mybatis ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 高级特性 1 一级缓存和二级缓存 一级缓存 二级缓存 2 延迟加载 5 整合Spring 1 MyBatis-Spring模块 2 事务管理 结…...

C语言与人生函数的对比,使用,参数详解

各位少年,大家好,我是博主那一脸阳光。,今天给大家分享函数的定义,和数学的函数的区别和使用 前言:C语言中的函数和数学中的函数在概念上有相似之处,但也存在显著的区别。下面对比它们的主要特点&#xff…...

机器人动力学一些笔记

动力学方程中,Q和q的关系(Q是sita) Q其实是一个向量,q(Q1,Q2,Q3,Q4,Q5,Q6)(假如6个关节) https://zhuanlan.zhihu.com/p/25789930 举个浅显易懂的例子,你在房…...

Plantuml之甘特图语法介绍(二十八)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...

Docker support for NVIDIA GPU Accelerated Computing on WSL 2

Docker support for NVIDIA GPU Accelerated Computing on WSL 2 0. 背景1. 安装 Docker Desktop2. 配置 Docker Desktop3. WLS Ubuntu 配置4. 安装 Docker-ce5. 安装 NVIDIA Container Toolkit6. 配置 Docker7. 运行一个 Sample Workload 0. 背景 今天尝试一下 NVIDIA GPU 在…...

SQL窗口函数大小详解

窗口大小 OVER 子句中的 frame_clause 选项用于指定一个滑动的窗口。窗口总是位于分区范围之内,是分区的一个子集。指定了窗口之后,分析函数不再基于分区进行计算,而是基于窗口内的数据进行计算。 指定窗口大小的语法如下: ROWS…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...