正则表达式梳理(基于python)
正则表达式(regular expression)是一种针对字符串匹配查找所定义的规则模式,独立于语言,但不同语言在实现上也会存在一些细微差别,下面基于python对常用的相关内容进行梳理。
文章目录
- 一、通用常识
- 1.通配符
- ps.反义
- 2.量词
- ps.非贪婪匹配
- 3.位置限定符
- 4.其他特殊符号
- 二、python实现
- 1.常用函数
- 1)search
- 2)match
- 3)findall
- 2.特殊用法
- 1) `(?:...) `非捕获组
- 2)`(?=...)`正向先行断言
- 3)`(?!...)`负向先行断言
- 4)`(?<=...)`正向后行断言
- 5)`(?<=...)`负向后行断言
- ps1.理解 先行/后行 & 正向/负向
- ps2.后行断言时,限定字符的长度必须固定
一、通用常识
1.通配符
.:匹配任意字符。(换行符除外)
\w:匹配字母、数字、下划线。(也可以写为[a-zA-Z0-9_])
\d:匹配阿拉伯数字([0-9])。
\s:匹配空白字符。(空格、制表符、换行符等)
[ ]:匹配列表中任意字符。(所有特殊字符在列表中都会按照字面量对待,不需要特殊转义)
ps.反义
\W:匹配非字母、数字、下划线外的字符。
\D:匹配非阿拉伯数字。
\S:匹配非空白字符。
[^ ]:不匹配列表中任意字符。
2.量词
?:0次或1次。
+:1次或多次。
*:0次或多次。
{m}:精确匹配m次。
{m,n}:匹配m~n次。
{m,}:至少匹配m次。
ps.非贪婪匹配
贪婪匹配:满足正则的情况下尽可能多的匹配。
非贪婪匹配:满足正则的情况下尽可能少的匹配。
默认正则中都是贪婪匹配,需要非贪婪匹配时需要在量词后面加个?。
3.位置限定符
^:限制起始字符。
$:限制结尾字符。
4.其他特殊符号
|:逻辑或,匹配逻辑或中的任意一个。
\:转义字符,通常对\本身进行转义。
二、python实现
python中实现正则的标准库是re,下面主要介绍该模块中常用的一些方法及作用。
1.常用函数
1)search
匹配目标字符串第一个出现的符合正则的子串,匹配成功返回Match对象,匹配失败返回None。
返回的Match对象可通过group方法获取指定捕获组()的内容,无论正则中有没有指定捕获组,默认的捕获组都是0,即整个符合正则的子串。
当在正则中显式指定捕获组时,捕获组索引号按照在正则中从左到右的顺序自1开始递增。
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import rematch = re.search(r'(\d+路)(\d+号)(\d+楼)', '北京市昌平区1路2号3楼')
print(match.group())
print(match.group(1))
print(match.group(2))
print(match.group(3))# 1路2号3楼
# 1路
# 2号
# 3楼
当出现捕获组嵌套的情况时,同样是按照在正则中从左往右出现的顺序解析对应,只不过是递归解析,类似于树的先序遍历。
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import rematch = re.search(r'((\d+路)(\d+号))(\d+楼)', '北京市昌平区1路2号3楼')
print(match.group())
print(match.group(1))
print(match.group(2))
print(match.group(3))
print(match.group(4))# 1路2号3楼
# 1路2号
# 1路
# 2号
# 3楼
2)match
match方法和search用法及返回的对象都一致,唯一的区别是search的目标子串可以出现在字符串中的任何位置,而match是从开头开始匹配,目标子串必须在字符串开头出现。
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import rematch = re.match(r'((\d+路)(\d+号))(\d+楼)', '北京市昌平区1路2号3楼')
if match:print(match.group())print(match.group(1))print(match.group(2))print(match.group(3))print(match.group(4))
else:print('None')# None
在正则前面加个.*适配就可以成功匹配了:
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import rematch = re.match(r'.*((\d+路)(\d+号))(\d+楼)', '北京市昌平区1路2号3楼')
if match:print(match.group())print(match.group(1))print(match.group(2))print(match.group(3))print(match.group(4))
else:print('None')# 北京市昌平区1路2号3楼
# 1路2号
# 1路
# 2号
# 3楼
3)findall
顾名思义,找出字符串中所有匹配正则的子串。无论有无匹配返回的结果都是一个列表。
当正则中无捕获组或者仅有一个捕获组时,返回的是包含单个元素的列表,每个元素都是一个匹配项。
无捕获组返回的是匹配整个正则的子串,1个捕获组返回的是匹配捕获组的子串。
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import reans1 = re.findall(r'\d+路\d+号\d+楼', '北京市昌平区1路2号3楼')
print(ans1)ans2 = re.findall(r'(\d+路)\d+号\d+楼', '北京市昌平区1路2号3楼')
print(ans2)# ['1路2号3楼']
# ['1路']
当正则中包含多个捕获组时,返回包含元组的列表,每个元组是一个正则匹配项,元组中的元素对应了每个匹配项中捕获组的匹配内容,无匹配时用空字符串''代替。
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import reans1 = re.findall(r'((\d+路)(\d+号))(\d+楼)', '北京市昌平区1路2号3楼')
print(ans1)ans2 = re.findall(r'((\d+路)?(\d+号))(\d+楼)', '北京市昌平区2号3楼')
print(ans2)# [('1路2号', '1路', '2号', '3楼')]
# [('2号', '', '2号', '3楼')]
ps:特别注意正则中包含逻辑或|时,无论匹配的是哪个逻辑分支,其余的逻辑分支中的捕获组都会在元组中用空字符串''表示。
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import reans = re.findall(r'B(\d+)层([A-Z]+)区|地下([一二三四五六七八九]+)层([A-Z]+)区','停车场B2层C区;停车场地下一层B区')
print(ans)# [('2', 'C', '', ''), ('', '', '一', 'B')]
2.特殊用法
1) (?:...) 非捕获组
仅匹配,不捕获。通常用于目标需要提取的捕获组前的限制规则比较复杂,需要用到()的场景。
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import reans = re.findall(r'(?:B|地下)[1-9一二三四五六七八九]+层([A-Z]+区)','停车场B2层C区;停车场地下一层B区')
print(ans)# ['C区', 'B区']
2)(?=...)正向先行断言
这里的正向先行的意思是,右侧必须出现可以匹配括号中...的字符,这种方式在实际匹配过程中只会预先查找,不会实际消耗字符串。
比如从下面的日期中提取月份:
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import rematch = re.search(r'\d+(?=月)', '今天是2025年3月5日')
if match:print(match)# <re.Match object; span=(8, 9), match='3'>
3)(?!...)负向先行断言
负向先行:右边不能出现匹配括号中...的字符。
提取日期号,不提取年和月份:
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import rematch = re.search(r'\d+(?![年月0-9])', '今天是2025年3月5日')
if match:print(match)# <re.Match object; span=(10, 11), match='5'>
4)(?<=...)正向后行断言
正向后行:左边必须出现匹配括号中...的字符。
只提取折扣价:
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import rematch = re.search(r'(?<=折扣价)\d+', '原价100;折扣价80;实付价70')
if match:print(match)# <re.Match object; span=(9, 11), match='80'>
5)(?<=...)负向后行断言
负向后行:左边不能出现匹配括号中...的字符。
只提取原价:
#!/usr/bin/env python3
# -*-coding:utf-8 -*-import rematch = re.search(r'(?<!(折扣价|实付价))\d+', '原价100;折扣价80;实付价70')
if match:print(match)# <re.Match object; span=(2, 5), match='100'>
ps1.理解 先行/后行 & 正向/负向
先行断言:检查匹配位置的 右侧 是否符合条件。
后行断言:检查匹配位置的 左侧 是否符合条件。
个人觉得,先行/后行 可以理解成目标匹配子串相对于限定字符的 左边/右边。
正向:匹配 存在 某个条件。
负向:匹配 不存在 某个条件。
ps2.后行断言时,限定字符的长度必须固定

内置文档中提示先行断言限定字符长度无特殊限制,后行断言限定字符长度必须固定。
原因是正则引擎的默认匹配方向是从左到右,当遇到先行断言时,引擎会临时向右扫描,检查后续字符是否符合断言条件。由于匹配方向与引擎的默认方向一致,变长模式不会导致回溯问题。
而后行断言时正则引擎需要反向检查左侧的字符,而反向匹配需要明确的起始位置。如果后行断言是变长模式(如.*、a+),引擎无法确定从哪个位置开始检查,导致性能下降或无法实现。
相关文章:
正则表达式梳理(基于python)
正则表达式(regular expression)是一种针对字符串匹配查找所定义的规则模式,独立于语言,但不同语言在实现上也会存在一些细微差别,下面基于python对常用的相关内容进行梳理。 文章目录 一、通用常识1.通配符ps.反义 2.…...
Scala 中 val 和对象内部状态的关系
在 Scala 中,val 用于声明不可变的变量,这意味着一旦 val 被赋值,它的引用(即指向的内存地址)就不能再改变。然而,这并不影响对象内部的状态(即对象的属性)是否可以改变。具体来说&a…...
skynet简单游戏服务器的迭代
在上一篇的基础上做了改进,主要三个更新: 基础框架引入多一层redis缓存,用于持久化数据,加速数据访问。原本需要通过mysql读取的操作,直接改成与redis层交互,redis会自动写入mysql,保证AP 最终…...
Python学习第八天
查看函数参数 操作之前给大家讲一个小技巧:如何查看函数的参数(因为python的底层源码是C语言并且不是开放的,也一直困扰着刚学习的我,这个参数叫什么名之类的看doc又总是需要翻译挺麻烦的)。 比如我们下面要说到的op…...
美股回测:历史高频分钟数据的分享下载与策略解析20250305
美股回测:历史高频分钟数据的分享下载与策略解析20250305 在金融分析和投资决策的精细化过程中,美股历史分钟高频数据发挥着至关重要的作用。这些数据以其详尽性和精确性,记录了股票每分钟的价格波动和成交量变化,为投资者提供了…...
【仿muduo库one thread one loop式并发服务器实现】
文章目录 一、项目介绍1-1、项目总体简介1-2、项目开发环境1-3、项目核心技术1-4、项目开发流程1-5、项目如何使用 二、框架设计2-1、功能模块划分2-1-1、SERVER模块2-1-2、协议模块 2-2、项目蓝图2-2-1、整体图2-2-2、模块关系图2-2-2-1、Connection 模块关系图2-2-2-2、Accep…...
服务流程设计和服务或端口重定向及其websocket等应用示例
服务流程设计和服务或端口重定向及其websocket等应用示例 目录 服务或端口重定向的服务设计和websocket等应用示例 一、通用请求控制流程 1.1、入口 1.2、所有GET请求首先预检控制单元 1.3、http请求会分别自动307重定向 1.4、所有请求首先执行跨源控制单元 1.5、然后…...
【数据库】关系代数
关系代数 一、关系代数的概念二、关系代数的运算2.1 并、差、交2.2 投影、选择2.3 笛卡尔积2.4 连接2.5 重命名2.6 优先级 一、关系代数的概念 关系代数是一种抽象的数据查询语言用对关系的运算来表达查询 运算对象:关系运算符:4类运算结果:…...
ubuntu20 安装python2
1. 确保启用了 Universe 仓库 在某些情况下,python2-minimal 包可能位于 Universe 仓库中。你可以通过以下命令启用 Universe 仓库并更新软件包列表: bash复制 sudo add-apt-repository universe sudo apt update 然后尝试安装: bash复制…...
MySQL无法连接到本地localhost的解决办法2024.11.8
问题描述:我的MySQL可以远程连接服务器,但无法连接自己的localhost。 错误提示: 2003 - Cant connet to MySQL server on localhost(10061 "Unknown error")查找问题原因: 1. 检查环境变量是否正确:发现没…...
【Leetcode 每日一题】1328. 破坏回文串
问题背景 给你一个由小写英文字母组成的回文字符串 p a l i n d r o m e palindrome palindrome,请你将其中 一个 字符用任意小写英文字母替换,使得结果字符串的 字典序最小 ,且 不是 回文串。 请你返回结果字符串。如果无法做到࿰…...
最新Spring Security实战教程(一)初识Spring Security安全框架
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Micro麦可乐的博客 🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战 🌺《RabbitMQ》…...
Docker的常用镜像
Docker的常用镜像命令主要包括镜像的查看、搜索、拉取、删除、构建等操作,以下是综合多个来源的总结: 一、基础镜像操作 查看本地镜像 docker images• 显示所有本地镜像,包含仓库名(REPOSITORY)、标签(TAG…...
告别GitHub连不上!一分钟快速访问方案
一、当GitHub抽风时,你是否也这样崩溃过? 😡 npm install卡在node-sass半小时不动😭 git clone到90%突然fatal: early EOF🤬 改了半天hosts文件,第二天又失效了... 根本原因:传统代理需要复杂…...
MapReduce 深度解析:原理与案例实战
在大数据时代,数据量的爆炸性增长对数据处理提出了前所未有的挑战。MapReduce 作为一种编程模型和并行处理框架,能够让我们在分布式环境下高效处理海量数据。本文将详细讲解 MapReduce 的基本原理、工作流程,并通过一个案例来展示如何应用这种…...
Android中的Fragment是什么以及它有哪些生命周期方法
Android中的Fragment介绍 Fragment,直译为“碎片”或“片段”,是Android中的一种组件,可以看作是Activity的模块化部分。它可以在一个Activity中承载一部分用户界面和逻辑,并能被多个Activity复用。通过Fragment,开发…...
Leetcode 1477. 找两个和为目标值且不重叠的子数组 前缀和+DP
原题链接: Leetcode 1477. 找两个和为目标值且不重叠的子数组 class Solution { public:int minSumOfLengths(vector<int>& arr, int target) {int narr.size();int sum0;int maxnINT_MAX;vector<int> dp(n,maxn);//dp[i]表示以索引i之前的满足要求…...
Ubuntu 22.04安装NVIDIA A30显卡驱动
一、安装前准备 1.禁用Nouveau驱动 Ubuntu默认使用开源Nouveau驱动,需要手动禁用: vim /etc/modprobe.d/blacklist-nouveau.conf # 添加以下内容: blacklist nouveau options nouveau modeset0 # 更新内核并重启: update-initr…...
R语言绘图:韦恩图
韦恩分析 韦恩分析(Venn Analysis)常用于可视化不同数据集之间的交集和并集。维恩图(Venn diagram),也叫文氏图、温氏图、韦恩图、范氏图,用于显示元素集合重叠区域的关系型图表,通过图形与图形…...
Stable Diffusion Prompt编写规范详解
Stable Diffusion Prompt编写规范详解 一、语法结构规范 (一)基础模板框架 [质量强化] [主体特征] [环境氛围] [风格控制] [镜头参数]质量强化:best quality, ultra detailed, 8k resolution主体特征:(1girl:1.3), long …...
大模型推理框架Triton使用教程:从青铜到王者的修炼
1 相关预备知识 模型:包含了大量参数的一个网络(参数结构),体积10MB-10GB不等模型格式:相同的模型可以有不同的存储格式(可类比音视频文件),目前主流有torch、tf、onnx和trt&#x…...
C#+Halcon 检测稳定性提升的方式
前言 众所周知,C#是一个带垃圾回收机制的语言,开发过程中不需要考虑垃圾回收,你就可劲造吧。但我们在设计图像处理软件时,应时刻对图像等大内存资源进行管控,做到自行管控,及时释放,不应将其交…...
智谱AI-FunctionCall
智谱AI-FunctionCall 编写FuncationCall大模型的函数调用,先直观的感受一下的感受下FunctionCall的魅力 文章目录 智谱AI-FunctionCall[toc]1-参考网址2-思路整理3-代码拆件1-[非核心]两个业务函数2-[非核心]业务函数的JsonSchema定义3-[核心]FunctionCall的调用1-打…...
android亮灭屏流程分析
前言 亮灭涉及的东西非常多,因此单独写一个文档,进行详细说明,亮灭屏包括的东西不只是亮灭屏,还包括亮度调节、屏幕状态变化等东西。本文仅作学习使用,不涉及商业,侵权请联系删除。 framework层的学习链接…...
Docker Desktop常见问题记录
1.docker pull报错,无法连接https://registry-1.docker.io/v2/ 报错信息如下: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection(Client.Timeout exceeded …...
vscode+vue前端开发环境配置
目录 一、安装Vue二、使用vue新建项目 一、安装Vue 在node.js安装好之后, npm config set registry https://registry.npmmirror.com# 安装vue相关工具,webpack用来项目构建、打包、资源整合等。 npm install webpack -g# 安装vue-cli脚手架 npm insta…...
Qt5 C++ QMap使用总结
文章目录 功能解释代码使用案例代码解释注意事项代码例子参考 功能解释 QList<T> QMap::values() const Returns a list containing all the values in the map, in ascending order of their keys. If a key is associated with multiple values, all of its values wi…...
《解锁HarmonyOS NEXT高阶玩法:艺术图像识别功能开发全攻略》
在当今数字化时代,AI技术不断拓展其应用边界,为各行业带来前所未有的变革。在艺术领域,AI图像识别技术能够帮助艺术从业者、爱好者快速识别艺术品风格、作者,甚至挖掘艺术品背后的历史文化信息。本文将结合HarmonyOS NEXT API 12及…...
post get 给后端传参数
post 方式一 : data: params 作为请求体(Request Body)传递: 你已经展示了这种方式,通过data字段直接传递一个对象或数组。这种方式通常用于传递复杂的数据结构。dowmfrom: function (params) { return request({ u…...
Masscan下载Linux安装
masscan 是一款高速的端口扫描工具,能够在极短的时间内扫描大量IP地址和端口。以下是关于如何在Linux系统上下载并安装 masscan 的详细步骤。 ### 通过包管理器安装 对于一些Linux发行版,你可以直接使用系统的包管理器来安装 masscan。例如,…...
