【python3】5.正则表达式

news2024/11/15 15:39:33
本学习内容总结于莫烦python:5.正则表达式
https://mofanpy.com/tutorials/python-basic/interactive-python/regex

5.正则表达式

本章较为重要,单独拿出来成章了

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配 比如我要批量修改很多文件中出现某种固定模式的文字时。
re 模块使 Python 语言拥有全部的正则表达式功能

5.1 不用正则判断

pattern1 = "file"
pattern2 = "files"
string = "the file is in the folder"
print("file in string", pattern1 in string)   
print("files in string", pattern2 in string)
file in string True
files in string False

做了一个判断,看有没有包含这个词。不过种类变多了之后,总写这样的判断,处理的能力是十分有限的。

正则的方法

方法一:规则用命名=re.compile(r);用命名.search("")比较

import re
# 命名=re.compile(r)
ptn = re.compile(r"\w+?@\w+?\.com")

#`命名.search()
matched = ptn.search("mofan@mofanpy.com")
print("mofan@mofanpy.com is a valid email:", matched)
matched = ptn.search("mofan@mofanpy+com")
print("mofan@mofanpy+com is a valid email:", matched)

\w:匹配所有字母数字,等同于 [a-zA-Z0-9_]
+:+号之前的字符出现 >=1 次
?: 在符号前面的字符为可选,即出现 0 或 1 次
+?:则是惰性匹配,不加是尽可能多的配,先尽可能少的配,这里: \w 至少匹配 1 次

现在有个字符串adsabopbc

  • 正则是a.+b,这种情况下这个正则表达式能匹配的就是adsabopb,因为中间的.+会保证在尽量能匹配成功的前提下尽量的多匹配字符;
  • 正则是a.+?b,那么匹配的结果就是adsab了,因为他会保证在尽量能匹配的成功的情况下少的匹配字符。

我都是用 r"xxx" 来写一个 pattern:因为正则表达式很多时候都要包含\,r 代表原生字符串, 使用 r 开头的字符串是为了不让你混淆 pattern 字符串中到底要写几个 \,你只要当成一个规则来记住在写 pattern 的时候,都写上一个 r 在前面就好了。

mofan@mofanpy.com is a valid email: <re.Match object; span=(0, 17), match='mofan@mofanpy.com'>
mofan@mofanpy+com is a valid email: None

re.Match object这个意思应该是匹配了 ,匹配的范围是[0,17),匹配内容是:mofan@mofanpy.com
没匹配 返回没有None

  • 方法二:re.search(r"规则","对象")
matched = re.search(r"\w+?@\w+?\.com", "the email is mofan@mofanpy.com.")
print("the email is mofan@mofanpy.com:", matched)
the email is mofan@mofanpy.com: <re.Match object; span=(13, 30), match='mofan@mofanpy.com'>

5.2 正则给额外信息

  • 提出匹配的内容match.group()
match = re.search(r"\w+?@\w+?\.com", "the email is mofan@mofanpy.com.")
print(match)
print(match.group())
<re.Match object; span=(13, 30), match='mofan@mofanpy.com'>
mofan@mofanpy.com

此处内容看视频】:https://www.bilibili.com/video/BV1ef4y1U7V4/

  • |:或 字符串
  • [au]:相当于字母间的a|u
re.search(r"ran|run", "I run to you") # match='run'
re.search(r"ra|un", "I run to you") # match='un'
re.search(r"r[au]n", "I run to you") # match='run'
  • (|):多字符串匹配
print(re.search(r"f(ou|i)nd", "I find you"))
print(re.search(r"f(ou|i)nd", "I found you"))
<re.Match object; span=(2, 6), match='find'>
<re.Match object; span=(2, 7), match='found'>

5.3 按类型匹配

https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md#232–%E5%8F%B7
在这里插入图片描述

5.4 中文

和英文一样用

print(re.search(r"不?爱", "我爱你"))
print(re.search(r"不?爱", "我不爱你"))
print(re.search(r"不.*?爱", "我不是很爱你"))
<re.Match object; span=(1, 2), match='爱'>
<re.Match object; span=(1, 3), match='不爱'>
<re.Match object; span=(1, 5), match='不是很爱'>

5.5 查找替换等更多功能

在这里插入图片描述

print("search:", re.search(r"run", "I run to you"))
print("match:", re.match(r"run", "I run to you"))
print("findall:", re.findall(r"r[ua]n", "I run to you. you ran to him"))

for i in re.finditer(r"r[ua]n", "I run to you. you ran to him"):
    print("finditer:", i)

print("split:", re.split(r"r[ua]n", "I run to you. you ran to him"))
print("sub:", re.sub(r"r[ua]n", "jump", "I run to you. you ran to him"))
print("subn:", re.subn(r"r[ua]n", "jump", "I run to you. you ran to him"))
search: <re.Match object; span=(2, 5), match='run'>
match: None
findall: ['run', 'ran']
finditer: <re.Match object; span=(2, 5), match='run'>
finditer: <re.Match object; span=(18, 21), match='ran'>
split: ['I ', ' to you. you ', ' to him']
sub: I jump to you. you jump to him
subn: ('I jump to you. you jump to him', 2)

5.6 在模式中获取特定信息

5.6.1 获取单一信息

想要提取出匹配模式当中的一些字段,而不是全字段。举个例子, 我的文件名千奇百怪,我就想找到 *.jpg 图片文件,而且只返回给我去掉 .jpg 之后的纯文件名

found = []
for i in re.finditer(r"[\w-]+?\.jpg", "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"):
    found.append(re.sub(r".jpg", "", i.group()))
print(found)
['2021-02-01', '2021-02-02', '2021-02-03']
  • [\w-]要么是数字字母,要么是-,二者选一;至少一个
  • re.sub(r"规则",“替换的内容”,“查找的语句”) :这里规则就是.jpg,用空替换,那么 i.group()提取出来"I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"中符合[\w-]+?\.jpg·规则的

上面这种做法虽然可行,但是还不够简单利索,因为同时用到了两个功能 finditer sub.改进:

string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
print("without ():", re.findall(r"[\w-]+?\.jpg", string))
print("with ():", re.findall(r"([\w-]+?)\.jpg", string))
without (): ['2021-02-01.jpg', '2021-02-02.jpg', '2021-02-03.jpg']
with (): ['2021-02-01', '2021-02-02', '2021-02-03']

  • re.findall:返回不重复。且符合规则列表
  • 加入一个():选定要截取返回的位置, 他就直接返回括号里的内容

5.6.2 获取多个信息

  • 方法一:re.finditer():去的还是字符串结构:"(\d+?)-(\d+?)-(\d+?)\.jpg" 因为用了(),规则就知道group分别指的什么了
string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
match = re.finditer(r"(\d+?)-(\d+?)-(\d+?)\.jpg", string)
for file in match:
    print("matched string:", file.group(0), ",year:", file.group(1), ", month:", file.group(2), ", day:", file.group(3))
matched string: 2021-02-01.jpg ,year: 2021 , month: 02 , day: 01
matched string: 2021-02-02.jpg ,year: 2021 , month: 02 , day: 02
matched string: 2021-02-03.jpg ,year: 2021 , month: 02 , day: 03
  • 方法二:re.findall() 去的直接是个列表,所以用【】
string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
match = re.findall(r"(\d+?)-(\d+?)-(\d+?)\.jpg", string)
for file in match:
    print("year:", file[0], ", month:", file[1], ", day:", file[2])
  • 变形,更便于编程:?P<索引名> 来进行对group标号
string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
match = re.finditer(r"(?P<y>\d+?)-(?P<m>\d+?)-(?P<d>\d+?)\.jpg", string)
for file in match:
    print("matched string:", file.group(0), 
        ", year:", file.group("y"), 
        ", month:", file.group("m"), 
        ", day:", file.group("d"))

5.7 多模式匹配

讲解了两个:大小写和分行的处理
在这里插入图片描述
以上都是用flag=

  • re.I 忽略大小写的例子
ptn, string = r"r[ua]n", "I Ran to you"
print("without re.I:", re.search(ptn, string))
print("with re.I:", re.search(ptn, string, flags=re.I))
without re.I: None
with re.I: <re.Match object; span=(2, 5), match='Ran'>

flags=re.I 用上这个就忽略了大小写

  • 多行匹配:re.M
ptn = r"^ran"
string = """I
ran to you"""
print("without re.M:", re.search(ptn, string))
print("with re.M:", re.search(ptn, string, flags=re.M))
print("with re.M and match:", re.match(ptn, string, flags=re.M))
without re.M: None
with re.M: <re.Match object; span=(2, 5), match='ran'>
with re.M and match: None

re.match() 是不管你有没有 re.M flag,我的匹配都是按照最头头上开始匹配的。 所以上面的实验中,re.match() 匹配不到任何东西

第二个我们想在每行文字的开头匹配特定字符,如果用 ^ran 固定样式开头,匹配不到第二行的 ran to you 的,所以我们得加上一个 re.M flag

  • 想同时用 re.M, re.I
ptn = r"^ran"
string = """I
Ran to you"""
print("with re.M and re.I:", re.search(ptn, string, flags=re.M|re.I))
with re.M and re.I: <re.Match object; span=(2, 5), match='Ran'>
  • 还有一种写法可以直接在 ptn 里面定义这些 flags
string = """I
Ran to you"""
re.search(r"(?im)^ran", string)
<re.Match object; span=(2, 5), match='Ran'>

flags: (?im) 这就是说要用· re.I, re.M

5.8 更快地执行

如果你要重复判断一个正则表达式.,5.1 的方法1 效率高于 方法2

import time
n = 1000000
# 不提前 compile
t0 = time.time()
for _ in range(n):
    re.search(r"ran", "I ran to you")
t1 = time.time()
print("不提前 compile 运行时间:", t1-t0)

# 先做 compile
ptn = re.compile(r"ran")
for _ in range(n):
    ptn.search("I ran to you")
print("提前 compile 运行时间:", time.time()-t1)
不提前 compile 运行时间: 1.9030001163482666
提前 compile 运行时间: 0.42299962043762207

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

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

相关文章

【数据结构】栈和队列的实现(C语言)

前言 栈和队列都是重要的线性结构&#xff0c;即在使用层面上收到限制而发挥特殊作用的线性表。掌握这两种结构在不同情景下亦会发挥重要作用。 栈 定义 栈保持着后进先出的原则&#xff0c;正因如此在插入数据的时候要求只能从一段插入&#xff0c;称为栈顶&#xff1b;相反另…

Arduino与Proteus仿真实例-电子相册仿真

电子相册仿真 本次实例将仿真如何从SD卡读取BMP格式图像并在ILI9341驱动器的LCD显示屏上显示。 1、仿真电路原理图 在仿真电路原理图中,SD卡通过SPI方式连接,ILI9341 LCD显示屏也是通过SPI方式连接。SD卡的CS引脚连接Arduino Mega2560的SS引脚(Pin10),显示屏的CS引脚连接…

竞赛——【蓝桥杯】2022年11月第十四届蓝桥杯模拟赛第一期Java

1、二进制位数 问题描述 十进制整数 2 在十进制中是 1 位数&#xff0c;在二进制中对应 10 &#xff0c;是 2 位数。 十进制整数 22 在十进制中是 2 位数&#xff0c;在二进制中对应 10110 &#xff0c;是 5 位数。 请问十进制整数 2022 在二进制中是几位数&#xff1f; 答案…

数据管理技术的发展经历了哪三个阶段

数据管理技术是指对数据进行分类、组织、编码、查询和维护&#xff0c;它是数据处理的中心问题&#xff1b; 随着计算机技术的不断发展&#xff0c;在应用需求的推动下&#xff0c;在计算机硬件、软件发展的基础上数据管理技术经历了人工管理、文件管理、数据库管理3个阶段。每…

CircRNA+代谢组如何冲击22分高分文章?

发表期刊&#xff1a;Cell Metabolism 影响因子&#xff1a;22.415 发表时间&#xff1a;2019年5月30日 合作单位&#xff1a;中国科学技术大学 Biotree协助客户中国科学技术大学吴缅教授和安徽医科大学胡汪来教授及其研究团队在国际顶尖期刊《Cell Metabolism》上发表名为…

跑通yolox-s官方源码(可与yolov5s做对比试验)

目录&#xff08;一&#xff09;一些参考链接&#xff08;二&#xff09;YOLOX训练自己的数据集&#xff0c;修改相应代码0. 自己的数据集文件夹排布1. 修改类别标签和数量1.1 修改类别标签 yolox/data/datasets/voc_classes.py1.2 修改类别数量 exps/example/yolox_voc/yolox_…

Quartus 实例应用(2)——创建设计工程

Quartus II 简易教程一、概念回顾二、创建设计工程2.1 创建工程2.2 新建HDL文件三、编译工程四、下载一、概念回顾 什么是综合&#xff1f;什么是设计&#xff1f; 答&#xff1a;综合就是编译&#xff0c;设计就是布局布线。 二、创建设计工程 2.1 创建工程 打开Quartus I…

用vuex对token/refresh_token 进行管理以及处理token过期问题

这里介绍对token的处理 问题1&#xff1a;token数据或者其他数据&#xff0c;存在vuex仓库中&#xff0c;刷新会丢失状态 。 问题2&#xff1a;数据只存在本地&#xff0c;数据变化了&#xff0c;相关的视图并不会更新。 Vuex 容器中的数据只是为了方便在其他任何地方能方便的获…

【EC200U】 基站定位

EC200U 基站定位什么是基站基站定位cellLocator - 基站定位调用获取坐标token 秘钥申请运行测试我们之前玩了GPS了【EC200U】GPS定位 GPS 精度高&#xff0c;但比较费电&#xff0c;首次搜索卫星定位时间比较长&#xff0c;当卫星信号覆盖不好&#xff0c;比如室内&#xff0c;…

gdb-dashboard的简单使用

问题描述 众所周知&#xff0c;随着IDE的普及&#xff0c;越来越多的人不习惯命令行调试&#xff0c;但是Linux开发又绕不开GDB&#xff0c;所以有大佬开发了程序用来显示常见的一些调试参数&#xff0c;gdb-dashboard是比较热门的程序之一。附链接。 使用参考 神仙GDB调试工…

Golang入门笔记(7)—— 函数 func

函数是什么&#xff1f; 函数&#xff1a;为完成某一功能的程序的语句指令的集合。 感觉重头戏逐渐到来了&#xff0c;让我们好好的&#xff0c;认真对待它吧&#xff01;为什么要使用函数&#xff1f; 为了提高代码的复用&#xff0c;减少代码的冗余&#xff0c;提高代码维护性…

前端框架 React 学习总结

目录 一、React在HTML里的运用 二、React框架的常用操作 1、JSX基础语法规则 2、state数据的使用 3、生命周期 4、数据的双向绑定与Ref 5、PropTypes验证规则 6、React里的插槽 7、错误边界 8、直接操作refs元素 9、高阶组件的运用案例 10、性能优化 11、Hook生命…

Linux中安装mysql8

一、下载MySQL到 /usr/local/src 1、打开官网下载界面 MySQL :: Download MySQL Community Server (Archived Versions) 2、选择某个版本的下载地址 以https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz这个地址作为例子 …

Kubernetes 系统化学习之 持久存储篇(五)

1. ConfigMap ConfigMap 是一种 API 对象&#xff0c;用来将非机密性的数据保存到键值对中。使用时&#xff0c;Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。ConfigMap 的主要作用就是为了让镜像和配置文件解耦&#xff0c;以便实现镜像的可移植性和可复用性…

day07 Elasticsearch搜索引擎3

day07 Elasticsearch搜索引擎3 1、数据聚合 聚合&#xff08;aggregations&#xff09;可以让我们极其方便的实现对文档数据的统计、分析、运算。例如&#xff1a; 什么品牌的手机最受欢迎&#xff1f;这些手机的平均价格、最高价格、最低价格&#xff1f;这些手机每月的销售…

java设计模式之观察者模式

一&#xff1a;观察者模式 1.什么是观察者模式? 观察者模式是一种行为设计模式&#xff0c; 允许你定义一种订阅机制&#xff0c; 可在对象事件发生时通知多个 “观察” 该对象的其他对象。 观察者模式的基本介绍 又被称为发布-订阅&#xff08;Publish/Subscribe&#xff09…

从阿里云容器攻防矩阵API安全生命周期,看如何构建金融安全云原生平台

【编者按】云原生技术正在助力银行通过差异化业务进行创新&#xff0c;却也带来了由于研发/运维人员对新架构不熟悉所导致的基础设施风险、业务风险及数据暴露风险。如何在飞速更迭的技术环境下保持业务持续发展&#xff0c;同时保证业务整体的安全性&#xff0c;满足不断增强的…

设计模式-装饰器模式

装饰器模式也称为包装模式是指在不改变原有对象的基础上&#xff0c;将功能附加到对象上&#xff0c;提供比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式 装饰器模式的核心是功能扩展,使用装饰器模式可以透明且动态的扩展类的功能 装饰器模式通用UML类图 主要角…

培训学校管理系统之家校管理

近年来&#xff0c;伴随着信息技术的进步。除了不少学校开展了数字化校园的建设&#xff0c;一些培训机构也在使用数字化系统进行管理。同时&#xff0c;由于招生数量的不断增长&#xff0c;如何解决学生、教师、家长三者之间的联系沟通问题&#xff0c;促进教学管理任务的有效…

排序(详解)

排序排序的概念常见的排序算法直接插入排序希尔排序&#xff08;缩小增量排序&#xff09;选择排序堆排序冒泡排序快排&#xff08;递归&#xff09;霍尔版本挖坑法前后指针法快排&#xff08;非递归&#xff09;归并排序&#xff08;递归&#xff09;归并排序&#xff08;非递…