Python正则表达式,看这一篇就够了
作者 | 猪哥
来源 | 裸睡的猪(ID: IT--Pig)
大多数编程语言的正则表达式设计都师从Perl,所以语法基本相似,不同的是每种语言都有自己的函数去支持正则,今天我们就来学习 Python中关于 正则表达式的函数。
re模块主要定义了9个常量、12个函数、1个异常,每个常量和函数猪哥都会通过实际代码案例讲解,让大家能更直观的了解其作用!
注:为避免出现代码格式错乱,猪哥尽量使用代码截图演示哦。
re模块简介
聊到Python正则表达式的支持,首先肯定会想到re
库,这是一个Python处理文本的标准库。
标准库的意思表示这是一个Python内置模块,不需要额外下载,目前Python内置模块大概有300个。可以在这里查看Python所有的内置模块:https://docs.python.org/3/py-modindex.html#cap-r
因为re是内置模块,所以不需要再下载,使用时直接引入即可:
import re
re模块官方文档:https://docs.python.org/zh-cn/3.8/library/re.html
re模块库源码:https://github.com/python/cpython/blob/3.8/Lib/re.py
re模块常量
常量即表示不可更改的变量,一般用于做标记。
re模块中有9个常量,常量的值都是int类型!
上图我们可以看到,所有的常量都是在RegexFlag枚举类来实现,这是在Python 3.6做的改版。在Python 3.6以前版本是直接将常量写在re.py中,使用枚举的好处就是方便管理和使用!
下面我们来快速学习这些常量的作用及如何使用他们,按常用度排序!
1. IGNORECASE
语法: re.IGNORECASE 或简写为 re.I
作用: 进行忽略大小写匹配。
代码案例:
在默认匹配模式下大写字母B无法匹配小写字母b,而在 忽略大小写 模式下是可以的。
2. ASCII
语法: re.ASCII 或简写为 re.A
作用: 顾名思义,ASCII表示ASCII码的意思,让 \w
, \W
, \b
, \B
, \d
, \D
, \s
和 \S
只匹配ASCII,而不是Unicode。
代码案例:
在默认匹配模式下\w+
匹配到了所有字符串,而在ASCII模式下,只匹配到了a、b、c(ASCII编码支持的字符)。
注意:这只对字符串匹配模式有效,对字节匹配模式无效。
3. DOTALL
语法: re.DOTALL 或简写为 re.S
作用: DOT表示.
,ALL表示所有,连起来就是.
匹配所有,包括换行符\n
。默认模式下.
是不能匹配行符\n
的。
代码案例:
在默认匹配模式下
.
并没有匹配换行符\n
,而是将字符串分开匹配;而在re.DOTALL模式下,换行符\n
与字符串一起被匹配到。
注意:默认匹配模式下.
并不会匹配换行符\n
。
4. MULTILINE
语法: re.MULTILINE 或简写为 re.M
作用:多行模式,当某字符串中有换行符\n
,默认模式下是不支持换行符特性的,比如:行开头 和 行结尾,而多行模式下是支持匹配行开头的。
代码案例:
正则表达式中
^
表示匹配行的开头,默认模式下它只能匹配字符串的开头;而在多行模式下,它还可以匹配 换行符\n
后面的字符。
注意:正则语法中^
匹配行开头、\A
匹配字符串开头,单行模式下它两效果一致,多行模式下\A
不能识别\n
。
5. VERBOSE
语法:re.VERBOSE 或简写为 re.X
作用:详细模式,可以在正则表达式中加注解!
代码案例:
默认模式下并不能识别正则表达式中的注释,而详细模式是可以识别的。
当一个正则表达式十分复杂的时候,详细模式或许能为你提供另一种注释方式,但它不应该成为炫技的手段,建议谨慎考虑后使用!
6.LOCALE
语法: re.LOCALE 或简写为 re.L
作用: 由当前语言区域决定 \w
, \W
, \b
, \B
和大小写敏感匹配,这个标记只能对byte样式有效。这个标记官方已经不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 “习惯”,而且只对8位字节有效。
注意: 由于这个标记官方已经不推荐使用,而且猪哥也没使用过,所以就不给出实际的案例!
7.UNICODE
语法: re.UNICODE 或简写为 re.U
作用: 与 ASCII 模式类似,匹配unicode编码支持的字符,但是 Python 3 默认字符串已经是Unicode,所以有点冗余。
8. DEBUG
语法: re.DEBUG
作用: 显示编译时的debug信息。
代码案例:
虽然debug模式下确实会打印编译信息,但猪哥并不理解这是什么语言 以及表达的含义,希望了解的朋友能不吝赐教。
9.TEMPLATE
语法: re.TEMPLATE 或简写为 re.T
作用: 猪哥也没搞懂TEMPLATE的具体用处,源码注释中写着:disable backtracking(禁用回溯),有了解的同学可以留言告知!
10. 常量总结
9个常量中,前5个(IGNORECASE、ASCII、DOTALL、MULTILINE、VERBOSE)有用处,两个(LOCALE、UNICODE)官方不建议使用、两个(TEMPLATE、DEBUG)试验性功能,不能依赖。
常量在re常用函数中都可以使用,查看源码可得知。
常量可叠加使用,因为常量值都是2的幂次方值,所以是可以叠加使用的,叠加时请使用
|
符号,请勿使用+
符号!
最后来一张思维导图总结一下re模块中的常量吧,需要高清图或者xmind文件的同学可在文章末尾获取。
re模块函数
re模块有12个函数,猪哥将以功能分类来讲解;这样更具有比较性,同时也方便记忆。
1.查找一个匹配项
查找并返回一个匹配项的函数有3个:search、match、fullmatch,他们的区别分别是:
search: 查找任意位置的匹配项
match: 必须从字符串开头匹配
fullmatch: 整个字符串与正则完全匹配
我们再来根据实际的代码案例比较:
案例1:
案例1中search函数是在字符串中任意位置匹配,只要有符合正则表达式的字符串就匹配成功,其实有两个匹配项,但search函数值返回一个。
而match函数是要从头开始匹配,而字符串开头多了个字母a
,所以无法匹配,fullmatch函数需要完全相同,故也不匹配!
案例2:
案例2删除了text最开头的字母a,这样match函数就可以匹配啦,而fullmatch函数依然不能完全匹配!
案例3:
案例3中,我们只留下一段文字,并且与正则表达式一致;这时fullmatch函数终于可以匹配了。
完整案例:
注意:查找 一个匹配项 返回的都是一个匹配对象(Match)。
2.查找多个匹配项
讲完查找一项,现在来看看查找多项吧,查找多项函数主要有:findall函数 与 finditer函数:
findall: 从字符串任意位置查找,返回一个列表
finditer:从字符串任意位置查找,返回一个迭代器
两个方法基本类似,只不过一个是返回列表,一个是返回迭代器。我们知道列表是一次性生成在内存中,而迭代器是需要使用时一点一点生成出来的,内存使用更优。
如果可能存在大量的匹配项的话,建议使用finditer函数,一般情况使用findall函数基本没啥影响。
3.分割
re.split(pattern, string, maxsplit=0, flags=0) 函数:用 pattern 分开 string , maxsplit表示最多进行分割次数, flags表示模式,就是上面我们讲解的常量!
注意:str模块也有一个 split函数 ,那这两个函数该怎么选呢?
str.split函数功能简单,不支持正则分割,而re.split支持正则。
关于二者的速度如何? 猪哥实际测试了一下,在相同数据量的情况下使用re.split
函数与str.split
函数执行次数 与 执行时间 对比图:
通过上图对比发现,1000次循环以内str.split
函数更快,而循环次数1000次以上后re.split
函数明显更快,而且次数越多差距越大!
所以结论是:在 不需要正则支持 且 数据量和数次不多 的情况下使用str.split
函数更合适,反之则使用re.split
函数。
注:具体执行时间与测试数据有关!
4.替换
替换主要有sub函数 与 subn函数,他们功能类似!
先来看看sub函数的用法:
re.sub(pattern, repl, string, count=0, flags=0) 函数参数讲解:repl替换掉string中被pattern匹配的字符, count表示最大替换次数,flags表示正则表达式的常量。
值得注意的是:sub函数中的入参:repl替换内容既可以是字符串,也可以是一个函数哦! 如果repl为函数时,只能有一个入参:Match匹配对象。
re.subn(pattern, repl, string, count=0, flags=0) 函数与 re.sub函数 功能一致,只不过返回一个元组 (字符串, 替换次数)。
5.编译正则对象
compile函数 与 template函数 将正则表达式的样式编译为一个 正则表达式对象 (正则对象Pattern),这个对象与re模块有同样的正则函数(后面我们会讲解Pattern正则对象)。
而template函数 与 compile函数 类似,只不过是增加了我们之前说的re.TEMPLATE 模式,我们可以看看源码。
6.其他
re.escape(pattern) 可以转义正则表达式中具有特殊含义的字符,比如:.
或者 *
,举个实际的案例:
re.escape(pattern) 看似非常好用省去了我们自己加转义,但是使用它很容易出现转义错误的问题,所以并不建议使用它转义,而建议大家自己手动转义!
re.purge() 函数作用就是清除 正则表达式缓存,具体有什么缓存呢?我们来看看源码就知道它背地里干了 什么:
看方法大概是清除缓存吧,我们再来看看具体的案例:
猪哥在两个案例之间使用了re.purge() 函数清除缓存,然后分别比较前后案例源码里面的缓存,看看是否有变化!
7.总结
同样,最后来一张思维导图总结一下re模块中的函数吧,需要高清图或者xmind文件的同学可在末尾获取。
re模块异常
re模块还包含了一个正则表达式的编译错误,当我们给出的正则表达式是一个无效的表达式(就是表达式本身有问题)时,就会raise一个异常!
我们来看看具体的案例吧:
上图案例中我们可以看到,在编写正则表达式中我们多写了一个后括号,这导致执行结果报错;而且是在其他所有案例执行之前,所以说明是在正则表达式编译时期就报错了。
注意:这个异常一定是 正则表达式 本身是无效的,与要匹配的字符串无关!
正则对象Pattern
关于re
模块的常量、函数、异常我们都讲解完毕,但是完全有必要再讲讲正则对象Pattern。
1. 与re模块 函数一致
在re
模块的函数中有一个重要的函数 compile函数 ,这个函数可以预编译返回一个正则对象,此正则对象拥有与re
模块相同的函数,我们来看看Pattern类的源码。
既然是一致的,那到底该用re模块 还是 正则对象Pattern ?
而且,有些同学可能看过re
模块的源码,你会发现其实compile函数 与 其他 re函数(search、split、sub等等) 内部调用的是同一个函数,最终还是调用正则对象的函数!
也就是说下面 两种代码写法底层实现 其实是一致的:
# re函数re.search(pattern, text)# 正则对象函数compile = re.compile(pattern)compile.search(text)
那还有必要使用compile函数 得到正则对象再去调用 search函数 吗?直接调用re.search 是不是就可以?
2. 官方文档怎么说
关于到底该用re模块 还是 正则对象Pattern ,官方文档是否有说明呢?
官方文档推荐:在多次使用某个正则表达式时推荐使用正则对象Pattern 以增加复用性,因为通过 re.compile(pattern) 编译后的模块级函数会被缓存!
3. 实际测试又如何?
上面官方文档推荐我们在 多次使用某个正则表达式时使用正则对象,那实际情况真的是这样的吗?
我们再实测一下吧
猪哥编写了两个函数,一个使用re.search函数 另一个使用 compile.search函数,分别(不同时)循环执行count次(count从1-1万),比较两者的耗时!
得出的结果猪哥绘制成折线图:
得出的结论是:100次循环以内两者的速度基本一致,当超出100次后,使用 正则对象Pattern 的函数 耗时明显更短,所以比re模块 要快!
通过实际测试得知:Python 官方文档推荐 多次使用某个正则表达式时使用正则对象函数 基本属实!
注意事项
Python 正则表达式知识基本讲解完毕,最后稍微给大家提一提需要注意的点。
1.字节串 与 字符串
模式和被搜索的字符串既可以是 Unicode 字符串 (str) ,也可以是8位字节串 (bytes)。但是,Unicode 字符串与8位字节串不能混用!
2.r 的作用
正则表达式使用反斜杠(’\’)来表示特殊形式,或者把特殊字符转义成普通字符。
而反斜杠在普通的 Python 字符串里也有相同的作用,所以就产生了冲突。
解决办法是对于正则表达式样式使用 Python 的原始字符串表示法;在带有 ‘r’ 前缀的字符串字面值中,反斜杠不必做任何特殊处理。
3.正则查找函数 返回匹配对象
查找一个匹配项(search、match、fullmatch)的函数返回值都是一个 匹配对象Match ,需要通过match.group() 获取匹配值,这个很容易忘记。
另外还需要注意:match.group() 与match.groups() 函数的差别!
4.重复使用某个正则
如果要重复使用某个正则表达式,推荐先使用 re.compile(pattern)函数 返回一个正则对象,然后复用这个正则对象,这样会更快!
5.Python 正则面试
笔试可能会遇到需要使用Python正则表达式,不过不会太难的,大家只要记住那几个方法的区别,会正确使用,基本问题不大。
文章所有内容精华猪哥已经整理成一份思维导图:链接(或阅读原文):https://pan.baidu.com/s/10MMpuf6Rcba-gvBo1oIzlw 密码:y6z3
【END】
今日福利
遇见陆奇
同样作为“百万人学 AI”的重要组成部分,2020 AIProCon 开发者万人大会将于 7 月 3 日至 4 日通过线上直播形式,让开发者们一站式学习了解当下 AI 的前沿技术研究、核心技术与应用以及企业案例的实践经验,同时还可以在线参加精彩多样的开发者沙龙与编程项目。参与前瞻系列活动、在线直播互动,不仅可以与上万名开发者们一起交流,还有机会赢取直播专属好礼,与技术大咖连麦。
门票限量大放送!今日起点击阅读原文报名「2020 AI开发者万人大会」,使用优惠码“AIP211”,即可免费获得价值299元的大会在线直播门票一张。限量100张,先到先得!快来动动手指,免费获取入会资格吧!
点击阅读原文,直达大会官网。
你点的每个“在看”,我都认真当成了AI
相关文章:
Spring MVC 4
Spring MVC 4 项目文件结构 pom.xml依赖 <properties><endorsed.dir>${project.build.directory}/endorsed</endorsed.dir><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies> …

SQL Server 2008高可用性系列:数据库快照
SQL Server 2008高可用性系列:数据库快照http://database.51cto.com 2010-09-13 14:45 我爱菊花 博客园 我要评论(0)摘要:我们今天要讨论的话题是数据库快照。在SQL Server 2008高可用性中,快照是一项很重要的内容,可以提供至…

PostgreSQL 9.3 beta2 stream replication primary standby switchover bug?
[更新]已有patch. 请参见.PostgreSQL 9.1,9.2,9.3 clean switchover Primary and Standby Patch. http://blog.163.com/digoal126/blog/static/16387704020136197354054/打补丁前的测试 : PostgreSQL 9.3 beta2 无法完成正常的主备角色切换.Primary : psql checkpont; pg_cont…

Apache commons-io
添加引用 <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency>按行写: public static void writeFileLineByApacheIO(String fileContent) throws…

Oracle Exadata 简介
随着企业业务的发展,大型数据仓库越来越多,其规模也在迅速扩大,平均每两年规模增大3倍。大型数据仓库要求以最高的磁盘读取速度扫描几十、几百或几千个磁盘,只有磁盘和服务器之间的管道带宽增加10倍或更多才能满足此要求ÿ…
推荐系统的价值观
作者丨gongyouliu来源丨大数据与人工智能(ID: ai-big-data)推荐系统作为满足人类不确定性需求的一种有效工具,是具有极大价值的,这种价值既体现在提升用户体验上,又体现在获取商业利润上。对绝大多数公司来说ÿ…

PostgreSQL md5 auth method introduce, with random salt protect
在上一篇BLOG中介绍了不要在pg_hba.conf中使用password认证方法, 除非你的客户端和数据库服务器之间的网络是绝对安全的.http://blog.163.com/digoal126/blog/static/1638770402013423102431541/MD5方法,认证过程 : Encrypting Passwords Across A Network The MD5 authenticat…
常用Maven收集以及Maven技巧
1.完整的Maven的pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"http://maven.apach…
大促下的智能运维挑战:阿里如何抗住“双11猫晚”?
作者 | 阿里文娱技术专家子霖出品 | AI科技大本营(ID:rgznai100)2019 双 11 猫晚在全球近 190 个国家和地区播出,海外重保是首要任务,如何提升海外用户观看猫晚的体验?本文将详解双 11 猫晚国际化的技术挑战和技术策略…

这次真的是下定决心了
这次我想是真的,真的。 上上周买了一本书 数据结构 c版 看到这本书的重点 线性表第三节,看不下去了,由于我模板学的不怎么样,数据结构c版大部分涉及了c 的模板,而且我觉得这本书上的代码有些漏洞。上上周买书的第三天…

子弹实例化的代码
using UnityEngine; using System.Collections;public class fire : MonoBehaviour {public float rate 0.2f;public GameObject bullet;private void Start(){OnFire();}//实例化子弹public void Fire(){GameObject.Instantiate(bullet, transform.position, Quaternion.iden…
Shiro源码学习之一
一.最基本的使用 1.Maven依赖 <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.2.4</version></dependency><dependency> <groupId>org.slf4j</groupId> …

传百度要与阿里、腾讯争夺在线办公市场?“百度Hi”开放520人同时在线音视频会议
在线办公市场持续火热。4月20日,百度旗下在线办公平台“百度Hi”再升级,正式发布业内大规模的520人音视频会议,并支持多入口快速入会,加码在线办公。另有消息称,4月底,百度在线办公平台将发布重磅升级&…

SQL 2008 安装资料及下载地址
SQL Server 2008 序列号: Developer: PTTFM-X467G-P7RH2-3Q6CG-4DMYB Enterprise: JD8Y6-HQG69-P9H84-XDTPG-34MBB 服务器设置SQL Server 代理 NT AUTHORITY\SYSTEMSQL Server Database Engine NT AUTHORITY\NETWORK SERVICE SQL Server Browser 默认 SQL Ser…

Objective-C非正式协议与正式协议
为什么80%的码农都做不了架构师?>>> 类别与类扩展的区别: ①类别中只能增加方法; ②是的,你没看错,类扩展不仅可以增加方法,还可以增加实例变量(或者合成属性)ÿ…
Shiro源码学习之二
接上一篇 Shiro源码学习之一 3.subject.login 进入login public void login(AuthenticationToken token) throws AuthenticationException {clearRunAsIdentitiesInternal();Subject subject securityManager.login(this, token);PrincipalCollection principals;String hos…

Widgets 整理
1.滑动条 http://www.newnaw.com/pub/sl/031.html <--!grid中的内容--> <Grid x:Name"slidergrid" HorizontalAlignment"Left" VerticalAlignment"Center" Background"Azure" Margin"20"> <StackPane…
黑客用上机器学习你慌不慌?这 7 种窃取数据的新手段快来认识一下!
作者 | IrrfanAk译者 | 天道酬勤、Carol 责编 | Carol出品 | AI科技大本营(ID:rgznai100)机器学习以分析大型数据集和模式识别的能力而闻名。它基本上属于人工智能的一个子集。而机器学习使用的算法,是利用了先前的数据集和统计分析来做出假设…

ServletResponse-中文名的下载
2019独角兽企业重金招聘Python工程师标准>>> package com.httpServletResponse; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.se…
Linux环境编译安装OpenJDK
Centos6.5 AMD64位机器 Java的源码是C,C和Java实现的,所以还需要有一个安装好的java建议选OracleJDK参考文末 安装OracleJDK Linux环境安装卸载JDK以及安装Tomcat和发布Java的web程序 安装依赖 | Install dependence # yum -y install gcc gcc-c alsa-lib alsa-…
最快69秒逆向DRAM地址映射,百度设计的这款逆向工具如何做到快速可靠?
来源 | 百度安全实验室出品 | AI科技大本营(ID:rgznai100)导读:近日,国际顶级设计自动化大会DAC大会公布DAC 2020会议议程和论文名单,由百度安全发表的《DRAMDig: AKnowledge-assisted Tool to Uncover DRAM Address M…

国外厂商在行业客户上输单的原因
这两天听一个朋友聊天发泄,他在一家总代J公司工作,代理业内排行第一的国外厂商C公司的产品,他负责D行业在南方某几个省的销售业务,工作中需要与C公司的销售紧密配合。经过接近一年的工作,他拿到一些项目,但…

[android] 从gallery获取图片
效果就是点击按钮,打开系统图库应用,可以选择一张里面的图片展示出来 设置隐式意图 获取Intent对象,通过new出来 调用Intent对象的setAction()方法,设置动作,参数:Intent.ACTION_PICK 调用Intent对象的setT…
调试JDK源码-HashSet实现原理
调试JDK源码-一步一步看HashMap怎么Hash和扩容 调试JDK源码-ConcurrentHashMap实现原理 调试JDK源码-HashSet实现原理 调试JDK源码-调试JDK源码-Hashtable实现原理以及线程安全的原因 代码 Set<String> snew HashSet<String>();s.add("http://blog.csdn.ne…
Python 炫技操作:海象运算符的三种用法
作者 | 明哥来源 | Python编程时光(ID:Cool-Python)Python 版本发展非常快,如今最新的版本已经是 Pyhton 3.9,即便如此,有很多人甚至还停留在 3.6 或者 3.7,连 3.8 还没用上。很多 Python 3.8 的特性还没来…

2010.10.30 OA 项目组一周工作报告
本周基本上实现了上周的目标,但和计划相比有落后。 进度:55 本周提交了3.0任务评估的第一个版本,一共为1003小时,客户收到该评估后,对3.0任务进行了调整,将部分任务移到2011.2版本中,同时添加了…

继承log4.net的类
using System; using System.Diagnostics;[assembly: log4net.Config.XmlConfigurator(Watch true)] namespace Hbl.Core {public static class Log{/// <summary>/// 一般错误/// </summary>/// <param name"message">消息</param>public …
调试JDK源码-Hashtable实现原理以及线程安全的原因
调试JDK源码-一步一步看HashMap怎么Hash和扩容 调试JDK源码-ConcurrentHashMap实现原理 调试JDK源码-HashSet实现原理 调试JDK源码-调试JDK源码-Hashtable实现原理以及线程安全的原因 Hashtable是线程安全的,我们从源码来分析 代码很简单 Hashtable<String, …

源代码查看工具 Source Navigator 使用心得
在ubuntu 10.04下试用了Source Navigator,有条件还是装Source insight吧,不是一个级别的,非常不方便。 Source Navigator 是Red Hat出品的一款查看源代码的工具,非常好用,与Windows下的Source Insight有一敌。但是它的…
那个分分钟处理10亿节点图计算的Plato,现在怎么样了?
受访者 | 于东海记者 | 夕颜出品 | CSDN(ID:CSDNnews)「AI 技术生态论」 人物访谈栏目是 CSDN 发起的百万人学 AI 倡议下的重要组成部分。通过对 AI 生态顶级大咖、创业者、行业 KOL 的访谈,反映其对于行业的思考、未来趋势的判断、技术的实践…