首页 > 编程语言 > 详细

Python的re模块

时间:2019-03-18 10:08:01      阅读:146      评论:0      收藏:0      [点我收藏+]

什么是re模块,re模块有什么作用?

re模块是Python提供的一个正则表达式相关的模块,主要是针对字符串进行模糊匹配,所以在字符串匹配这一功能上,re相当专业。

什么是模糊匹配?

之前的学习字符串内容的时候,也有进行匹配的一些方法,比如find()方法:

S = adnsanpnqbciqwocb
ret = S.find(san)
print(ret)
>>> 3

这样就可以获得"san"在S中的位置,这种方法称为精确匹配。但很多情况下我们提供的搜索条件并没有那么精确,比如“四条腿”,在大脑中检索出来的答案就有四条腿的桌子、四条腿的兔子等等,这种粗略的搜索就可以理解为模糊匹配

在re中,匹配的参数可以是普通字符,也可以是元字符,这里用re中最常用的findall()函数举例,findall()函数就是找出目标字符串中所有的复合模板要求的字符串。

import re

ret = re.findall(pengfy,dainbqbfepengfyxMONDW434)
print(ret)
>>> [‘pengfy‘]

元字符主要有:. ^ $ * + ? {} [] () | \

我们在findall()函数中中演示这几个元字符的用法,先看元字符 . ^ $ * + ? {}

.叫通配符能能够代表任意字符(\n除外),需要代表几个就写几个.,举例如下:

import re

ret = re.findall(p..g,d123pengfyPENGFYpANgyq)
print(ret)  #找出所有p开头g结尾的字符串,区分大小写
>>>[peng, pANg]

ret = re.findall(p..g,d123pe\ngfy)
print(ret)  #不能代表\n
>>>[]

^我们老师管它叫尖角符,只能从字符串的开头进行匹配,$刚好相反,只能从字符串的结尾进行匹配,举例如下:

(注意^和$放的位置,也是一头一尾)

import re

ret = re.findall(^p..g,pengfyPENGFYpANgyq)
print(ret)  #只能从头开始匹配
>>> [peng]

ret = re.findall(p..g$,pengfyPENGFYpANgyqpang)
print(ret)  #只能从尾部开始匹配
>>>[pang]

ret = re.findall(^p..g$,pengfyPengFYpANg)
print(ret)  #一起使用不会报错,但也不会有结果,这不是一种有效的用法
>>>[]

如果有多个重复的字母,我们用.表示显然很麻烦,这种情况我们可以用* + {}

*表示可以重复0或多次

+表示可以重复1或多次

{}可以指定重复的次数

一定程度上,{}可以表示成* +

分别举例如下:

import re

ret = re.findall(peng*,6ghpenggggggfwf)
print(ret)
>>>[pengggggg]

ret = re.findall(peng*,6ghpenfwf)
print(ret)
>>>[pen]

ret = re.findall(peng+,6ghpenggggggfwf)
print(ret)
>>>[pengggggg]

ret = re.findall(peng+,6ghpenfwf)
print(ret)   #和*的区别
>>>[]

ret = re.findall(peng{0,8},6ghpenggggggfwf)
print(ret)  
>>>[pengggggg]

ret = re.findall(peng{0},6ghpenggggggfwf)
print(ret)
>>>[pen]

ret = re.findall(peng{0,},6ghpenggggggfwf)
print(ret)   #不加逗号就只匹配0个g,加上就默认0到无穷,和*一样
>>>[pengggggg]

ret = re.findall(peng{8},6ghpenggggggfwf)
print(ret)
>>>[]  #指定个数没达到,就没有匹配值

ret = re.findall(peng{},6ghpenggggggfwf)
print(ret) #不指定区间,也没有匹配值
>>> []

通过以上实例,大家可以看到,只要匹配到的,我们都是返回重复最多的结果,这种匹配叫贪婪匹配,如何取消,那就是使用问号 ?,举例如下:

import re
ret = re.findall(peng*?,6ghpenggggggfwf)
print(ret)   #最小重复0次
>>>[pen]

ret = re.findall(peng+?,6ghpenggggggfwf)
print(ret)    #最小重复1次
>>>[peng]

ret = re.findall(peng{2,8}?,6ghpenggggggfwf)
print(ret)    #最小重复指定次数,这里是2
>>>[pengg]

可以看到,加上?后,匹配的都变成了最小重复次数,这种匹配叫惰性匹配

接下来看[],还是举例说明:

import re

ret = re.findall(www.[taobao,baidu].com,wwwww.baidu.commmm)
print(ret)
>>>[]

ret = re.findall(www.[taobao,baidu].com,wwwww.b.commmm)
print(ret)
>>>[www.b.com]

ret = re.findall(www.[taobao,baidu].com,wwwww.,.commmm)
print(ret)
>>>[www.,.com]

通过上面的例子可以看到,[]里面,每个元素都独立存在,包括逗号,里面的关系可以理解成或的关系,但是在[]中的元素基本都没有自身的意义,

但有三个符号是有意义的,分别是 - ^ \

import re

ret = re.findall([a-z],AJo;AHIcnwi1890jlk)
print(ret)  #按ASSIC码表区范围
>>>[o, c, n, w, i, j, l, k]

ret = re.findall([^a-z],AJo;AHIcnwi1890jlk)
print(ret)
>>>[A, J, ;, A, H, I, 1, 8, 9, 0]

ret = re.findall([a\-z],AJo;AHIcnwz1890jlk)
print(ret)   #取消了-的特殊功能,[]中就剩下a或-或z三个元素
>>>[z]

ret = re.findall([\^a-z],AJo;AHIcnwi1890jlk)
print(ret)   #取消了^的特殊功能,[]中就剩下^和a-z之间的字母
>>>[o, c, n, w, i, j, l, k]

ret = re.findall([c\.w],AJo;AHIcnwi1890j.lk)
print(ret)   #取消了.的特殊功能,[]中就剩下c或.或w三个元素
>>>[c, w, .]

前面两个比较好理解,-就是一个范围,^就是非的意思,只要不是[]中的元素就可以匹配,\的功能就是取消元字符的特殊功能,但\还有一个功能,下面开始讲解\

1.反斜杠后边跟元字符去除特殊功能,比如\.
2.反斜杠后边跟普通字符实现特殊功能,比如\d

第一个上面已经演示过了,下面看第二个功能:

\d  匹配任何十进制数;它相当于类 [0-9]。
\D 匹配任何非数字字符;它相当于类 [^0-9]。
\s  匹配任何空白字符;它相当于类 [ \t\n\r\f\v]。
\S 匹配任何非空白字符;它相当于类 [^ \t\n\r\f\v]。
\w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
\W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
\b  匹配一个特殊字符边界,比如空格 ,&,#等

还是通过实例展示一下:

import re

ret = re.findall(\d,AJo;AHIcnwi1890j.lk)
print(ret)
<<<[1, 8, 9, 0]

ret = re.findall(\D,AJo;.lk)
print(ret)
>>>[A, J, o, ;, ., l, k]

ret = re.findall(\s,I am Pengfy)
print(ret)
>>>[ ,  ]

ret = re.findall(\S,I am Pengfy)
print(ret)
>>>[I, a, m, P, e, n, g, f, y]

ret = re.findall(\w,I am,18YEARSOLD.)
print(ret)
>>>[I, a, m, 1, 8, Y, E, A, R, S, O, L, D]

ret = re.findall(\W,I am,18YEARSOLD.)
print(ret)
>>> , ,, .]

ret = re.findall(I\b,Y&I are boy)
print(ret)
>>>[]

 

前面几个应该都能理解,看到最后一个,什么鬼,怎么没有返回数据啊?不要慌,这里要从Python运行机制去解释,先看下面几个例子:

import re

ret=re.findall(y\z,penfgy\ze)
print(ret)  #程序报错:bad escape \z at position 1

ret=re.findall(y\\z,penfgy\ze)
print(ret)  #程序报错:bad escape \z at position 1

ret=re.findall(y\\\\z,penfgy\ze)
print(ret)
>>>[y\\z]

ret=re.findall(ry\\z,penfgy\ze)
print(ret)
>>>[y\\z]

我们可以看到,需要传四个反斜杠才能输出正常结果,为什么呢?因为\是给re模块识别的,但是在Python解释器中,\b又有别的意思,所以需要加一个r,至于为什么我们看到的结果为什么是两个反斜杠,这也是解释器的原因导致,其实在re中是一个。

技术分享图片

ret = re.findall(rI\b,I am Iboy &I is)
print(ret)
>>>[I, I]

加上r以后,就能正常匹配了,r是干什么的呢?r的作用就是告诉解释器,里面的东西不要编译,原封不动的给到re

还剩下()和管道符 |,()是用于分组,比如:

import re

ret=re.findall(r(ab)+,abbbbbbcd)
print(ret)
>>>[ab]

import re
ret=re.findall(r(bcd),abbbbbbcdbcdbcd)
print(ret)
>>>[bcd, bcd, bcd]

ret=re.findall((?P<id>\d{2})/(?P<name>\w{3}),23/com23com255/yyyy)
print(ret)
>>>[(23, com), (55, yyy)]

ret=re.search((?P<id>\d{2})/(?P<name>\w{3}),23/com23com255/yyyy)
print(ret)  #返回的只是一个地址
print(ret.group())
print(ret.group(name)) #可以单独取一个
>>>  <re.Match object; span=(0, 6), match=23/com>
>>>  23/com
>>>  com

 上面(?P<id>)这种用法直接记住就好了,原理很难讲清楚。接下来看管道符的用法:

import re

ret=re.findall(www.baidu|google.com,www.baidu.com,www.google.com)
print(ret)  #管道两边是或的关系
>>> [www.baidu, google.com]

到这里,元字符的用法就讲完了,下面讲一下re模块中的其他函数用法,re模块主要有findall() search() match() split() sub() compile() finditer()几个函数:

search()函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

import re
ret = re.search(p..g,666pengfy888pangyq).group()
print(ret)
>>> peng

match()函数和search()函数用法相同,但只能匹配字符串的开头

ret = re.match(p..g,666pengfy888pangyq)
print(ret)  #这里返回一个None,加上group()就报错了
>>> None

ret = re.match(p..g,pengfy888pangyq).group()
print(ret)
>>> peng

split()看起来并不陌生,在字符串的处理中也有一样的方法,这个就可以选择按什么方法进行切割:

ret = re.split([bc],abcde)
print(ret)  #这里是先按b分割成a、cde,cde再按c分割成‘‘、de
>>> [a, ‘‘, de]

 sub(),作用是替换,字符串中类似方法叫replace,直接看实例:

import re

set = re.sub(\d,peng,haoren66haode546fwerwef,2)
print(set)  #后面2这个参数,是替换的个数,本例中表示就替换前2个
print(type(set))  #输出的会是一个字符串

>>> haorenpengpenghaode546fwerwef
>>> <class str>

compile()的目的就是将匹配的方法赋值,这样使用多次的时候回相对简单一些:

func = re.compile(p..g*)
ret = func.findall(penggggfy888panggyq)
ret1 = func.search(penggggfy888panggyq).group()
print(ret,ret1)
>>>[pengggg, pangg] pengggg

finditer(),一看这个名字diter,其实就是iterator迭代器,用法和findall()差不多,然后使用next方法一个个取出来就好了:

ret = re.finditer(p..g+,666penggggfy888panggyq)
print(ret)
print(next(ret).group())
print(next(ret).group())

>>><callable_iterator object at 0x000001F6CA11E908> >>>pengggg
>>>pengg

以上就是对re模块的总结。

 

Python的re模块

原文:https://www.cnblogs.com/pengfy/p/10544094.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!