正则表达式 python_Python正则表达式总结

f772f43ae5ef2bd0e2f8e6eb1acbf919.png

之前我们讲解了 正则表达式 的起源、发展、流派、语法、引擎、优化等相关知识,今天我们主要来学习一下 正则表达式在 Python语言 中的应用

大多数编程语言的正则表达式设计都师从Perl,所以语法基本相似,不同的是每种语言都有自己的函数去支持正则,今天我们就来学习 Python中关于 正则表达式的函数。83ce981cbd76483177b2204664f0b2f6.pngre模块主要定义了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.htmlre模块库源码:https://github.com/python/cpython/blob/3.8/Lib/re.py

二、re模块常量

常量即表示不可更改的变量,一般用于做标记。re模块中有9个常量,常量的值都是int类型!711fa4c57b241ce32a6396ac9d739dee.png上图我们可以看到,所有的常量都是在RegexFlag枚举类来实现,这是在Python 3.6做的改版。在Python 3.6以前版本是直接将常量写在re.py中,使用枚举的好处就是方便管理和使用!1403394e385ae7c13d170cd5b17ac791.png下面我们来快速学习这些常量的作用及如何使用他们,按常用度排序!

1. IGNORECASE

语法: re.IGNORECASE 或简写为 re.I作用: 进行忽略大小写匹配。代码案例:f5bb37fdaebe1baedbe0c152485ac472.png在默认匹配模式下大写字母B无法匹配小写字母b,而在 忽略大小写 模式下是可以的。

2. ASCII

语法: re.ASCII 或简写为 re.A作用: 顾名思义,ASCII表示ASCII码的意思,让 \w, \W, \b, \B, \d, \D, \s\S只匹配ASCII,而不是Unicode。代码案例:8d15c0d3a7ed4815f8674f2213049471.png在默认匹配模式下\w+匹配到了所有字符串,而在ASCII模式下,只匹配到了a、b、c(ASCII编码支持的字符)。注意:这只对字符串匹配模式有效,对字节匹配模式无效。

3. DOTALL

语法: re.DOTALL 或简写为 re.S作用: DOT表示.,ALL表示所有,连起来就是.匹配所有,包括换行符\n默认模式下.是不能匹配行符\n代码案例:143744c2105c6549d637aad40f7ba1c6.png在默认匹配模式下.并没有匹配换行符\n,而是将字符串分开匹配;而在re.DOTALL模式下,换行符\n与字符串一起被匹配到。注意:默认匹配模式下.并不会匹配换行符\n

4. MULTILINE

语法: re.MULTILINE 或简写为 re.M作用:多行模式,当某字符串中有换行符\n,默认模式下是不支持换行符特性的,比如:行开头 和 行结尾,而多行模式下是支持匹配行开头的。代码案例:9e5feea87eb5a320b403e5ee8cedcc35.png正则表达式中^表示匹配行的开头,默认模式下它只能匹配字符串的开头;而在多行模式下,它还可以匹配 换行符\n后面的字符。注意:正则语法中^匹配行开头、\A匹配字符串开头,单行模式下它两效果一致,多行模式下\A不能识别\n

5. VERBOSE

语法:re.VERBOSE 或简写为 re.X作用:详细模式,可以在正则表达式中加注解!代码案例:fdedb5a78493d5f5e5c8e6b92463c2ff.png默认模式下并不能识别正则表达式中的注释,而详细模式是可以识别的。当一个正则表达式十分复杂的时候,详细模式或许能为你提供另一种注释方式,但它不应该成为炫技的手段,建议谨慎考虑后使用!

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信息。代码案例:0adde6784b411ff49d853dcfe3fd7773.png虽然debug模式下确实会打印编译信息,但猪哥并不理解这是什么语言 以及表达的含义,希望了解的朋友能不吝赐教。

9.TEMPLATE

语法: re.TEMPLATE  或简写为 re.T作用:猪哥也没搞懂TEMPLATE的具体用处,源码注释中写着:disable backtracking(禁用回溯),有了解的同学可以留言告知!ce9fa35bbefe8edc6ce20a83fbe721fe.png

10. 常量总结

  1. 9个常量中,前5个(IGNORECASE、ASCII、DOTALL、MULTILINE、VERBOSE)有用处,两个(LOCALE、UNICODE)官方不建议使用、两个(TEMPLATE、DEBUG)试验性功能,不能依赖。
  2. 常量在re常用函数中都可以使用,查看源码可得知。f13c5bfa1639d2dec4217ffa50073d15.png
  3. 常量可叠加使用,因为常量值都是2的幂次方值,所以是可以叠加使用的,叠加时请使用 | 符号,请勿使用+ 符号!74e560927740d33bef49ff1cba52717b.png
最后来一张思维导图总结一下re模块中的常量吧,需要高清图或者xmind文件的同学可在文章末尾获取。bfac9c7484a649961843799c60272666.png

三、re模块函数

re模块有12个函数,猪哥将以功能分类来讲解;这样更具有比较性,同时也方便记忆。

1.查找一个匹配项

查找并返回一个匹配项的函数有3个:search、match、fullmatch,他们的区别分别是:
  1. search 查找任意位置的匹配项

  2. match 必须从字符串开头匹配

  3. fullmatch 整个字符串与正则完全匹配

我们再来根据实际的代码案例比较:案例1:37a53f2d70c3f0a3de48a1ac38f815b7.png案例1中search函数是在字符串中任意位置匹配,只要有符合正则表达式的字符串就匹配成功,其实有两个匹配项,但search函数值返回一个。而match函数是要从头开始匹配,而字符串开头多了个字母a,所以无法匹配,fullmatch函数需要完全相同,故也不匹配!案例2:f6e1277fcb149d0d718d72d3f97b6bf0.png案例2删除了text最开头的字母a,这样match函数就可以匹配啦,而fullmatch函数依然不能完全匹配!案例3:158b59c590248f0084246379b50d7334.png案例3中,我们只留下一段文字,并且与正则表达式一致;这时fullmatch函数终于可以匹配了。完整案例:0fce58f98f5d35733e529c9544e22ce6.png注意:查找 一个匹配项 返回的都是一个匹配对象(Match)。

2.查找多个匹配项

讲完查找一项,现在来看看查找多项吧,查找多项函数主要有:findall函数finditer函数
  1. findall 从字符串任意位置查找,返回一个列表

  2. finditer:从字符串任意位置查找,返回一个迭代器

两个方法基本类似,只不过一个是返回列表,一个是返回迭代器。我们知道列表是一次性生成在内存中,而迭代器是需要使用时一点一点生成出来的,内存使用更优。3ebf7c8ea6a6e77043ef20c3b5c9b1d3.png如果可能存在大量的匹配项的话,建议使用finditer函数,一般情况使用findall函数基本没啥影响。

3.分割

re.split(pattern, string, maxsplit=0, flags=0) 函数:用 pattern 分开 string , maxsplit表示最多进行分割次数, flags表示模式,就是上面我们讲解的常量!9b623c713aad4af890ac0d1e30b675a7.png注意:str模块也有一个 split函数 ,那这两个函数该怎么选呢?str.split函数功能简单,不支持正则分割,而re.split支持正则。关于二者的速度如何?猪哥实际测试了一下,在相同数据量的情况下使用re.split函数与str.split函数执行次数  与 执行时间 对比图:46cabda6dd629edc15df486d84a45d59.png通过上图对比发现,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匹配对象。1376cb71878155fdadbe14bd55dae183.pngre.subn(pattern, repl, string, count=0, flags=0) 函数与 re.sub函数 功能一致,只不过返回一个元组 (字符串, 替换次数)。892b317c17b114ad7d83f68fd62c4179.png

5.编译正则对象

compile函数template函数 将正则表达式的样式编译为一个 正则表达式对象 (正则对象Pattern),这个对象与re模块有同样的正则函数(后面我们会讲解Pattern正则对象)。9e66908a63e27ec211bf3bd356fca4ab.pngtemplate函数compile函数 类似,只不过是增加了我们之前说的re.TEMPLATE 模式,我们可以看看源码。107740edcdd920932b4fb5dd10d7953e.png

6.其他

re.escape(pattern)可以转义正则表达式中具有特殊含义的字符,比如:.或者 *,举个实际的案例:2026948377f2955b6aa9f63a5a114cb0.pngre.escape(pattern) 看似非常好用省去了我们自己加转义,但是使用它很容易出现转义错误的问题,所以并不建议使用它转义,而建议大家自己手动转义re.purge()函数作用就是清除 正则表达式缓存,具体有什么缓存呢?我们来看看源码就知道它背地里干了 什么:7195155d0f86adedaca63e56ddc5546c.png看方法大概是清除缓存吧,我们再来看看具体的案例:fb755a53b072dd97a9afd5e1c1ee0559.png猪哥在两个案例之间使用了re.purge() 函数清除缓存,然后分别比较前后案例源码里面的缓存,看看是否有变化!c931f80232c0cd564ce6eba3a037d090.png

7.总结

同样,最后来一张思维导图总结一下re模块中的函数吧,需要高清图或者xmind文件的同学可在末尾获取。a79a652494e277c948b1cef1a630d615.png

四、re模块异常

re模块还包含了一个正则表达式的编译错误,当我们给出的正则表达式是一个无效的表达式(就是表达式本身有问题)时,就会raise一个异常!我们来看看具体的案例吧:c4123a83830b9973e89ba47a78673396.png上图案例中我们可以看到,在编写正则表达式中我们多写了一个后括号,这导致执行结果报错;而且是在其他所有案例执行之前,所以说明是在正则表达式编译时期就报错了。注意:这个异常一定是 正则表达式 本身是无效的,与要匹配的字符串无关!

五、正则对象Pattern

关于re模块的常量、函数、异常我们都讲解完毕,但是完全有必要再讲讲正则对象Pattern

1.  与re模块 函数一致

re模块的函数中有一个重要的函数 compile函数 ,这个函数可以预编译返回一个正则对象,此正则对象拥有与re模块相同的函数,我们来看看Pattern类的源码。2cd7205203bcd41fc7ccabd75faaf453.png既然是一致的,那到底该用re模块 还是 正则对象Pattern ?而且,有些同学可能看过re模块的源码,你会发现其实compile函数 与 其他 re函数(search、split、sub等等) 内部调用的是同一个函数,最终还是调用正则对象的函数!874106fa0174a87f691776fa7a0a280f.png也就是说下面 两种代码写法底层实现 其实是一致的:
# re函数re.search(pattern, text)# 正则对象函数compile = re.compile(pattern)compile.search(text)
那还有必要使用compile函数 得到正则对象再去调用 search函数 吗?直接调用re.search 是不是就可以?

2. 官方文档怎么说

关于到底该用re模块 还是 正则对象Pattern ,官方文档是否有说明呢?109d28569522b936dce3ad8938fc5697.png官方文档推荐:在多次使用某个正则表达式时推荐使用正则对象Pattern以增加复用性,因为通过 re.compile(pattern) 编译后的模块级函数会被缓存!

3. 实际测试又如何?

上面官方文档推荐我们在 多次使用某个正则表达式时使用正则对象,那实际情况真的是这样的吗?我们再实测一下吧78fb88c911b6e98569c06ff1b09baf4f.png猪哥编写了两个函数,一个使用re.search函数 另一个使用 compile.search函数 ,分别(不同时)循环执行count次(count从1-1万),比较两者的耗时!得出的结果绘制成折线图:f254730d2755c642a8e5eede32b97ffe.png得出的结论是: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() 获取匹配值,这个很容易忘记。6e5a29ed8c7d2f3821c4cf5ecbce9673.png另外还需要注意:match.group()match.groups() 函数的差别!

4.重复使用某个正则

如果要重复使用某个正则表达式,推荐先使用 re.compile(pattern)函数 返回一个正则对象,然后复用这个正则对象,这样会更快!

5.Python 正则面试

笔试可能会遇到需要使用Python正则表达式,不过不会太难的,大家只要记住那几个方法的区别,会正确使用,基本问题不大。文章所有内容精华作者已经整理成一份思维导图:

最后感谢大家阅读,希望大家能学有所成~

关注公众号资料不断更新……

 7451c543b2538c04f21fe318e55dc037.gif

46773c9ceccf43fed073aefd006c9d04.png

37a6fa5f64335e149f0767bcf8e21b2f.png

JuliaPython云编程

微信扫码关注,避免失联

37a6fa5f64335e149f0767bcf8e21b2f.png好文章,我在看❤️

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

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

相关文章

【HDU - 5912】Fraction (模拟)

题干: Mr. Frog recently studied how to add two fractions up, and he came up with an evil idea to trouble you by asking you to calculate the result of the formula below: As a talent, can you figure out the answer correctly? Input The first …

vue mysql webapp_基于Laravel+VueJS实战开发WebAPP

资源介绍【课程内容】1-git库与开发环境及工具软件介绍2-安装laravel框架3-安装laravel-ide-helper增强代码提示4-配置数据库与使用migrations创建表5-解决mysql5.7以下laravel不能执行数据迁移的问题6-合理的路由布局与分组路由7-远程开发环境服务器搭建与虚拟面板的使用8-使用…

计算机测试怎么提交,Win7电脑怎么测试上传速度?

做网站的人都知道上传速度是很重要的,因为太差的上传速度会影响工作的进度,所以他们经常要对上传速度进行测试,但是有一些新手不知道Win7电脑怎么测试上传速度?为此小编赶紧整理了以下教程,不知道的朋友赶紧来看看吧&a…

harmonyos消息服务器,第三方纯HarmonyOS应用太少,你还愿意升级吗?

部分纯鸿蒙 HarmonyOS 应用已上线:图标多了“HMOS”角标标识,而只有真正的鸿蒙系统应用才能真正体验到万能卡片等系列的功能,但是很明显目前真正属于鸿蒙系统的第三方应用太少……基本上都是华为自身的应用,那么如果应用太少你还愿…

300英雄服务器维护多久,《300英雄》2021年5月20日6:00-9:00更新维护公告

尊敬的《300英雄》玩家:《300英雄》将于2021年5月20日6:00-9:00(星期四),对所有大区进行停机更新,更新期间,您将无法登录游戏。如果在预定时间内无法完成维护内容,开服时间也将继续顺延。具体更新内容如下:一、活动相关…

服务器2008系统如何设置休眠时间,Win7休眠和睡眠怎么开启(Win2008)

如果把 Win7休眠和睡眠关闭了,需要的时候可以用命令重新开启,毕竟这两个功能不但可以节约电,还可以迅速恢复工作状态,节约开机开软件的时间。Win2008 R2 跟 Win7 同一内核,开启休眠和睡眠的命令也一样。在开启休眠和睡…

如何将文件拷贝服务器上,如何将文件复制到云服务器上

如何将文件复制到云服务器上 内容精选换一换将文件上传至Windows云服务器一般会采用MSTSC远程桌面连接的方式。本节为您介绍本地Windows计算机通过远程桌面连接,上传文件至Windows云服务器的操作方法。Windows云服务器可以访问公网。在本地Windows计算机上&#xff…

mysql5.7解压版错误_mysql 5.7 解压版 安装net start mysql 发生系统错误 2

1.配置环境变量 用户变量path 添加 mysql 安装目录2.新建my.ini文件 放到E:\mysql-5.7.24-winx64安装目录下[mysqld]port 3306basedirC:/software/mysql-5.7.21-winx64datadirC:/software/mysql-5.7.21-winx64/datamax_connections200character-set-serverutf8default-storage…

浪潮服务器建立虚拟驱动器,像《十二时辰》一样去建立标准! 浪潮这款服务器做到了...

原标题:像《十二时辰》一样去建立标准! 浪潮这款服务器做到了这个夏天,《长安十二时辰》制霸屏幕开画至今豆瓣评分达到8.8分现已成功“出海”在Amazon、Youtube、Viki付费上线成为唐风古韵的又一风向标现如今,越洋的标准可不止悠悠…

【AtCoder - 2554】Choose Integers (找规律,或枚举)

题干: Problem Statement We ask you to select some number of positive integers, and calculate the sum of them. It is allowed to select as many integers as you like, and as large integers as you wish. You have to follow these, however: each sele…

1m带宽可以做mysql数据库吗_服务器的1M带宽够用吗?1M网速是多少?

1M是什么?通常,在计算机中1M表示的是计算机的内存容量,即1M1024KB。但有不同的含义,云服务器中1M表示服务器的带宽,即1M带宽。在服务器中1M带宽够用吗?云服务器的1兆网速是多少?首先把云服务器带…

【POJ - 2318】TOYS(计算几何,叉积判断点与直线位置关系,二分)

题干: Calculate the number of toys that land in each bin of a partitioned toy box. Mom and dad have a problem - their child John never puts his toys away when he is finished playing with them. They gave John a rectangular box to put his toys i…

【HDU - 1968】【UVA - 12096】The SetStack Computer (模拟,集合求交集并集操作,STL实现)

题干: Background from Wikipedia: 揝et theory is a branch of mathematics created principally by the German mathematician Georg Cantor at the end of the 19th century. Initially controversial, set theory has come to play the role of a foundational…

【HDU - 1465 】不容易系列之一 (组合数学,错排)

题干: 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了! 做好“一件”事情尚且不易,若想永远成功而总从不失败,那更是难上加难了,就像花钱总是比挣钱容易的道理一…

java redis 重连_突破Java面试(23-4) - Redis 复制原理

全是干货的技术号:本文已收录在github,欢迎 star/fork:在Redis复制的基础上(不包括Redis Cluster或Redis Sentinel作为附加层提供的高可用功能),使用和配置主从复制非常简单,能使得从 Redis 服务器(下文称 slave)能精确…

python列表浅复制_Python列表深浅复制详解

转自:https://www.cnblogs.com/blaomao/p/7239203.html在文章《Python 数据类型》里边介绍了列表的用法,其中列表有个 copy() 方法,意思是复制一个相同的列表。例如1 names ["小明", "小红", "小黑", "小…

【CodeForces - 735B】Urbanization (找规律,思维)

题干: Local authorities have heard a lot about combinatorial abilities of Ostap Bender so they decided to ask his help in the question of urbanization. There are n people who plan to move to the cities. The wealth of the i of them is equal to a…

java 文本查找_Java基于正则表达式实现查找匹配的文本功能【经典实例】

本文实例讲述了Java基于正则表达式实现查找匹配的文本功能。分享给大家供大家参考,具体如下:REMatch.java:package reMatch;import java.util.regex.Matcher;import java.util.regex.Pattern;/*** Created by Frank*/public class REMatch {p…

java 前后的区别_java中前后++的区别

java中前后的区别发布时间:2020-06-22 14:38:22来源:亿速云阅读:134作者:Leah这篇文章将为大家详细讲解有关java中前后的区别,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章…

java中实现线程互斥的关键词_简单的互斥同步方式——synchronized关键字详解

2. synchronized的原理和实现细节2.1 synchronized可以用在那些地方静态方法,锁对象为当前类的class对象,不用显式指定实例方法,锁对象为当前实例对象,不用显式指定同步代码块,锁对象为括号中指定的对象,必须显式指定被synchronized修饰的方法或者代码块,同一时刻只…