Python一文轻松搞定正则匹配

一、前言

    日常工作中,不可避免需要进行文件及内容的查找,替换操作,python的正则匹配无疑是专门针对改场景而出现的,灵活地运用可以极大地提高效率,下图是本文内容概览。

二、正则表达式符号

    对于所有的正则匹配表达式,都可由4部分组成:基础字符,次数匹配,位置匹配,分组匹配,即

          正则匹配表达式= 基础字符(必选)+次数匹配(可选)+位置匹配(可选)+分组匹配(可选)

2.1 基础字符

    基础字符主要是对应与具体的匹配对象,常用的如下表,其中涉及有特殊含义的字符,如.,*,^,$等,如果要匹配该字符本身,需要使用转移符号"\"。

代码示例:

import re
string="lucky^ /696/   ^money \Healthy **"
pattern_num=re.compile("\d")  #匹配数字
num=pattern_num.findall(string)
pattern_letter=re.compile("\w")   #匹配字母或数字
letter=pattern_letter.findall(string)
pattern_blank=re.compile("\s")   #匹配空格
blank=pattern_blank.findall(string)
pattern_slash=re.compile(r"\\")    #匹配反斜杠\
slash=pattern_slash.findall(string)
pattern_tri=re.compile("\^")    #匹配特殊字符^
tri=pattern_tri.findall(string)
print("num:%s\nletter:%s\nblank:%s\nslash:%s\ntri:%s"%(num,letter,blank,slash,tri))

查询结果,注意\s表示单个空格,连续两个空格是作为两个结果,单反斜杠\的结果slash表示用“\\”,如果使用print函数打印查看实际是单斜杠\

2.2 匹配次数

    在设置了具体匹配字符后,还可以对字符匹配的数量进行限制,即在匹配字符后面加上匹配次数字符即可

代码示例

import re
string="lucky^ \/696/\   ^money//  \Healthy 12**"
pattern_num=re.compile("\d+")  #匹配至少1个数字
num=pattern_num.findall(string)
pattern_letter=re.compile("\w{4,5}")   #匹配4-5个字母或数字
letter=pattern_letter.findall(string)
pattern_blank=re.compile("\s{3}")   #匹配3个连续的空格
blank=pattern_blank.findall(string)
pattern_slash=re.compile(r"/{2,}")    #匹配至少两个反斜杠//
slash=pattern_slash.findall(string)
pattern_tri=re.compile("\d|\^")    #匹配数字或特殊字符^
tri=pattern_tri.findall(string)
print("num:%s\nletter:%s\nblank:%s\nslash:%s\ntri:%s"%(num,letter,blank,slash,tri))

查询结果

2.3 匹配位置

    同限制匹配字符的数量类似,可以设置匹配字符的位置,如指定开头或结尾的字符

代码示例

import re
string="luckyhappy happy-dog /happy, happy_test ^money  Healthy 12**happy**"
pattern_head=re.compile("^luc")  #匹配以luc开头的字符
head=pattern_head.findall(string)  #匹配成功
print("head",head)
pattern_head1=re.compile("^money")  #匹配以money开头的字符
head1=pattern_head1.findall(string)  #匹配失败
print("head1",head1)
pattern_tail=re.compile("\*$")  #匹配结尾为*的字符
tail=pattern_tail.findall(string)  #匹配成功
print("tail",tail)
pattern_tail1=re.compile("money$")  #匹配结尾为money的字符
tail1=pattern_tail1.findall(string)  #匹配失败
print("tail1",tail1)
pattern_limit=re.compile(r"\bhappy\b")  #匹配字符串中的单词happy,如果happy左右两侧都是字母数字下划线,注意前面需加r
limit=pattern_limit.findall(string)  #匹配成功,其中luckyhappy和happy_test不属于匹配成功的对象
print("limit",limit)

结果

2.3.1 ^与\A,$与\Z

注意^和\A,$和\Z看似都匹配开头和结尾,但在多行模式下存在差异,如下例子

import re
str = "Have a wonderful\nhope in python\nstudy"  #str内容为3行,\n表示换行
# 使用^
print("^ in slnle line:",re.findall("^hope", str))  # 默认单行模式,执照字符串的行首匹配,找不到匹配项
print("^ in multiple line:",re.findall("^hope", str, re.MULTILINE))  # 在多行模式下找到匹配项,会匹配其他行的行首
# 使用\A
print("\A in slnle line:",re.findall("\Ahope", str))  # 默认单行模式,执照字符串的行首匹配,找不到匹配项
print("\A in multiple line:",re.findall("\Ahope", str, re.MULTILINE))  # 在多行模式下,依然不会匹配其他行的行首
# 使用$
print("$ in slnle line:",re.findall("python$", str))  # 默认单行模式,执照字符串的行首匹配,找不到匹配项
print("$ in multiple line:",re.findall("python$", str, re.MULTILINE))  # 在多行模式下找到匹配项,会匹配其他行的行首
# 使用\Z
print("\Z in slnle line:",re.findall("python\Z", str))  # 默认单行模式,执照字符串的行首匹配,找不到匹配项
print("\Z in multiple line:",re.findall("python\Z", str, re.MULTILINE))  # 在多行模式下,依然不会匹配其他行的行首

匹配结果

2.4 分组匹配

示例代码

import re
str = "Zyp Have a 626 wonderful hello hope in python *** study"
pattern=re.compile("(Zyp).*([0-9]{3}).*(\*{3})")    #创建3个group查询
result=pattern.match(str)
print("All content:",result.group(0))   #group[0]为原始字符串
print("Name:",result.group(1))     #查找的结果下标从1开始
print("Value",result.group(2))
print("Count:",result.group(3))

结果

三、匹配函数

    ​前面内容已对匹配表达式进行了介绍,下面将介绍一些常用的查找函数,查找的条件也就是匹配表达式。主要有match,search,findall,finditer,sub,下表是它们之间的差异

3.1 compile

compile函数不是匹配函数,主要是用于生成pattern对象,供匹配函数使用,好处是可以将该规则重复使用。

   语法: re.compile(pattern, flags=0)pattern : 匹配规则flags : 标志位,默认为0,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

关于其中的flags,可配置如下值

re.I 忽略大小写

re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境

re.M 多行模式

re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)

re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库

re.X 为了增加可读性,忽略空格和 # 后面的注释

示例代码

import re
str ="Zyp Have a 626 wonderful hello hope in python *** study"
str2="Hwq Have a 888 wonderful hello hope in python * study"
pattern=re.compile("(\w{3}).*([0-9]{3}).*(\*)")    #创建3个group查询
result=pattern.match(str)
result2=pattern.match(str2)    #直接复用pattern,直接修改用于匹配的对象
print("Name:",result.group(1),result2.group(1))     #查找的结果下标从1开始
print("Value",result.group(2),result2.group(2))
print("Count:",result.group(3),result2.group(3))

匹配结果

3.2 match

match需要注意的是匹配是从行首位置开始,如果行首位置不存在匹配的结果,纵使后面存在可匹配的字符,依旧搜索不到,并且如果行首匹配成功,则直接返回结果,只进行一次匹配操作,不会继续对后面的进行匹配,

   语法: re.match(pattern, string, flags=0)pattern : 匹配规则string : 用于正则匹配的字符串。flags : 标志位,默认为0,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

代码示例

匹配结果,返回的结果为一个match对象

3.3 search

search作用与match类似,只进行一次匹配,但不会限制于在行首位置匹配,可在任意位置进行匹配,仍以match中的字符串示例

   语法: re.search(pattern, string, flags=0)pattern : 匹配规则string : 用于正则匹配的字符串。flags : 标志位,默认为0,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

代码示例

匹配结果,两个字符串str,str1都匹配到了符合规则的结果,返回的结果为一个match对象

3.4 findall

findall从名称可看出是查询所有符合的匹配项,并且返回的结果类型为列表,仍以相同的例子为例,多加了一个1314

   语法: re.findall(pattern, string, flags=0)pattern : 匹配规则string : 用于正则匹配的字符串。flags : 标志位,默认为0,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

示例代码

匹配结果,两个字符串的查询结果一致

3.5 finditer

finditer作用与findall相同,也是查询所有符合条件的结果,区别是返回的结果为迭代器,而不是列表。同时迭代表结果的查看可通过函数group或groups进行查看,但groups查看结果,必须匹配规则pattern中设置了分组形式,否则查找的内容为空元组。

   语法: re.finditer(pattern, string, flags=0)pattern : 匹配规则string : 用于正则匹配的字符串。flags : 标志位,默认为0,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

示例代码

匹配结果

3.6 sub

   语法: re.sub(pattern, repl, string, count=0, flags=0)pattern : 匹配规则repl : 用于替换匹配结果的新字符串。string : 用于正则匹配的字符串。count : 设置匹配后的替换次数,默认 0 表示替换所有的匹配结果。flags : 编译时用的匹配模式。

代码示例

import re
str ="Zyp Have a 626 wonderful hello hope 520 in python 1314*** study"  #str存在2个3位,1个4位的数字,
pattern=re.compile("[0-9]{3}")    #匹配一个3位的数字
result=re.sub(pattern,"999",str,count=2)   #对于查询到的3位数字用999替换,只替换2次
print("result:",result)

替换结果,原先3位的数字前面2个都已替换位999,因只替换2次,第3个1314不进行替换

四、常用场景

下面将针对一些常用的场景提供对应的匹配规则

正则表达式	含义
[3]	匹配数字“3”,即指定匹配的具体数字
[c]	匹配字母“c”,即指定匹配的具体字符
[0-9]	匹配一个数字
[^0-9]	匹配一个除0-9外的字符
[a-z]	匹配一个小写字母
[A-Z]	匹配一个大写字母
[a-zA-Z]	匹配一个字母
[^a-z]	匹配一个非小写字母的字符
^\d{4}-\d{1,2}-\d{1,2}	匹配以“-”形式分隔的日期,如2024-5-2
\d{18}|\d{17}[X]$	匹配出身份证号码
\d+\.\d+\.\d+\.\d+	匹配IP地址
^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$	匹配电子邮箱

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

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

相关文章

MySQL的DML语句

文章目录 ☃️概述☃️DML☃️添加数据☃️更新和删除数据☃️DML的重要性 ☃️概述 MySQL 通用语法分类 ● DDL: 数据定义语言,用来 定义数据库对象(数据库、表、字段) ● DML: 数据操作语言,用来对数据库表中的数据进行增删改 …

Android系统揭秘(一)-Activity启动流程(上)

public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread (IApplicationThread) contextThread; … try { … int result …

TCP 和 UDP 可以同时绑定相同的端口吗?

在网络编程中,TCP和UDP都可以绑定到同一个端口上进行通信。TCP和UDP是OSI模型中的传输层协议,它们分别使用不同的端口号来区分不同的应用程序或服务。 TCP(Transmission Control Protocol)提供了面向连接的、可靠的传输服务&…

新零售解决方案:线上线下融合,驱动现代商业新浪潮-亿发

在数字化和智能化的商业环境中,新零售正在迅速改变传统的商业模式。作为新时代的零售解决方案,新零售通过线上线下深度结合,为企业提供了更灵活、高效的运营方式。本文将探讨新零售的四大特征,并详细描述其在中小企业中的应用&…

虚拟机没关机,电脑直接关机导致虚拟机无法使用

虚拟机没关机,电脑直接关机导致虚拟机无法使用 虚拟机未正常关机 无法打开虚拟机,移除 删除虚拟机目录下的该文件夹CentOSXX.vmx.lck(或者重新命名) 虚拟机正常打开

二,SpringFramework

二、SpringFramework实战指南 目录 一、技术体系结构 1.1 总体技术体系1.2 框架概念和理解 二、SpringFramework介绍 2.1 Spring 和 SpringFramework概念2.2 SpringFramework主要功能模块2.3 SpringFramework 主要优势 三、Spring IoC容器和核心概念 3.1 组件和组件管理概念3…

一句话、10秒,我用Claude 3.5 Sonnet生成了完整的俄罗斯方块!

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,所以创建了“AI信息Gap”这个公众号,专注于分享AI全维度知识…

Python应用开发——30天学习Streamlit Python包进行APP的构建(7)

st.data_editor 显示数据编辑器 widget。 数据编辑器 widget 可让你在类似表格的用户界面中编辑数据框和许多其他数据结构。 警告 When going from st.experimental_data_editor to st.data_editor in 1.23.0, the data editors representation in st.session_state was ch…

2352.相等行列对

给你一个下标从 0 开始、大小为 n x n 的整数矩阵 grid ,返回满足 Ri 行和 Cj 列相等的行列对 (Ri, Cj) 的数目。 如果行和列以相同的顺序包含相同的元素(即相等的数组),则认为二者是相等的。 示例 1: 输入&#xff1a…

Java——包

一、包 1、简要介绍 在Java编程语言中,包(Package) 是一种用来组织和管理类(Class)和接口(Interface)的机制。包为开发者提供了一种逻辑分组的方式,使代码更加模块化、结构化和易于…

【前端技术】标签页通讯localStorage、BroadcastChannel、SharedWorker的技术详解

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…

Redis大key有什么危害?如何排查和处理?

什么是 bigkey? 简单来说,如果一个 key 对应的 value 所占用的内存比较大,那这个 key 就可以看作是 bigkey。具体多大才算大呢?有一个不是特别精确的参考标准: String 类型的 value 超过 1MB 复合类型(Li…

一个漂亮的网站收藏函数

<!DOCTYPE html> <html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>网站收藏</title><style>body …

云手机群控功能讲解

接触云手机之前&#xff0c;很多企业或者个人卖家都对群控有浓厚的兴趣&#xff0c;云手机群控具体是什么呢&#xff1f;云手机群控&#xff0c;顾名思义&#xff0c;是指能够同时对多台云手机进行集中控制和管理的功能。打破了传统单台手机操作的限制&#xff0c;实现了规模化…

高精度乘法的实现

这是C算法基础-基础算法专栏的第九篇文章&#xff0c;专栏详情请见此处。 引入 上次我们学习了高精度加法的实现&#xff0c;这次我们要学习高精度减法的实现。 高精度乘法与高精度加法的定义、前置过程都是大致相同的&#xff0c;如果想了解具体内容&#xff0c;可以移步至我的…

查看LabVIEW及各个模块和驱动的版本号

要方便地查看当前计算机上安装的LabVIEW版本以及各个模块和驱动的版本号&#xff0c;可以使用以下几种方法&#xff1a; 1. 使用NI MAX (Measurement & Automation Explorer) NI MAX 是一个强大的工具&#xff0c;可以帮助你管理National Instruments硬件、软件和驱动程序…

Docker(三)-Docker常用命令

1.run run命令执行流程:2.帮助启动类命令 2.1 启动docker systemctl start docker2.2 停止docker systemctl stop docker2.3 重启docker systemctl restart docker2.4查看docker状态 systemctl status docker2.5开机启动 systemctl enable docker2.6查看docker概要信息 …

VB.net实战(VSTO):VSTOwpf体验框架打包教程

如果是考虑到Wps用户较多&#xff0c;就不建议采用侧边栏的形式 只是个体验框架&#xff0c;界面未作美化&#xff0c;office的用户可以用任意一种窗体&#xff0c;喜欢那个界面就写那个界面&#xff0c;wps的侧边栏只能弹出一部分&#xff0c;每次需要的手动拖动。 打包了案例…

Java——IO流(一)-(6/8):字节流-FileInputStream 每次读取多个字节(示例演示)、一次读取完全部字节(方式一、方式二,注意事项)

目录 文件字节输入流&#xff1a;每次读取多个字节 实例演示 注意事项 文件字节输入流&#xff1a;一次读取完全部字节 方式一 方式二 注意事项 文件字节输入流&#xff1a;每次读取多个字节 用到之前介绍过的常用方法&#xff1a; 实例演示 需求&#xff1a;用每次读取…

诸茅的黄昏

内容提要 白酒大陆的坍塌终于到达茅台的地盘&#xff0c;一切发生得太快了。突然间&#xff0c;深厚的护城河消失了&#xff0c;医药茅、眼科茅、牙科茅、疫苗茅、酱油茅都挣扎于内需的泥沼中。旧茅衰退&#xff0c;新茅生长&#xff0c;在下行周期&#xff0c;内需仍有结构性…