re正则表达式
re模块
re又名正则表达式,是一种小型语言,其作用范围为字符串,内嵌在python中,通过调用re模块实现,其底层通过C语言编写的匹配法则进行匹配
作用目的:通过编写的匹配规则对字符串进行模糊匹配,比字符串内置方法更为强大,字符串内置方法只能进行精准匹配
元字符
字符分为普通字符与元字符,通过元字符的组合可以达到模糊匹配的规则
普通字符没有特殊功能,可以跟自身进行匹配
print(re.findall("app","ajkaappurl"))#['app']
元字符:. * ^ $ + ? {} \ []
注意:元字符匹配都属于贪婪匹配,即最多次匹配
具体用法:“.”,通配符,可以代指所有内容,但换行符\n除外,且一个.只能代指一个字符
“*”,跟在一个字符后面,用以表示可以重复前面字符的次数,范围[0,正无穷)
”+”,跟在字符后面,类似*,但范围为[1,正无穷)
“?”,跟在字符后面,类似*,范围为[0,1]
“{}”,跟在字符后面,也是重复匹配,但可以定义匹配次数或匹配范围
“^”,写在规则前面,表示从第一个字符开始匹配
“$”,写在规则后面,表示从后面开始匹配
1 import re 2 print(re.findall("t.m","oqqoqjqtomqoq")) #表示匹配以t开头以m结尾中间可以是任意一个字符串且连在一起的一个字符串 3 4 print(re.findall("to*","qoqotoooooalkjqljq")) #匹配以t开头后面跟o字符且o字符个数范围可以为0-无穷多个 5 6 print(re.findall("to+","qjkqjtoooajjk")) #匹配以t开头且后面跟o字符且o字符个数范围可以为1—无穷多个 7 8 print(re.findall("to?","qoqotooamla")) #匹配以t开头且后面跟o字符且o字符个数范围为0-1个 9 10 print(re.findall("to{2}","qoqqotooomlqj")) #匹配以t开头且后面跟o字符且o字符个数为两个 11 12 print(re.findall("^to","tomakjajl")) #匹配以to开头的字符串 13 14 print(re.findall("to$","akjqqiqoto")) #匹配以to结尾的字符串
元字符之字符集[]
字符集用[]表示
作用:1.或的用法 2.取消元字符的特殊功能("\" ,"^","-"除外)3.[^]取反,即相当于去除掉[]中的内容
1 import re 2 print(re.findall("[ab]","qqjqajkjkbqijqabkk;"))#['a', 'b', 'a', 'b'] 对[]中单个字符进行或的匹配
1 print(re.findall("[^abc]","qoqoazbfjk"))#['q', 'o', 'q', 'o', 'z', 'f', 'j', 'k'] 去除掉掉a,b,c,
元字符之转译符"\"
用法:1.反斜杠后边跟元字符去除特殊功能
2.反斜杠后边跟普通字符实现特殊功能
常用功能:
\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 print(re.findall("\d","ajkaja12324akjk")) #['1', '2', '3', '2', '4'] print(re.findall("\D","ajqjq123jlkajfakoi473")) #['a', 'j', 'q', 'j', 'q', 'j', 'l', 'k', 'a', 'j', 'f', 'a', 'k', 'o', 'i'] print(re.findall("\s","akjfak akq akjfkj")) #[' ', ' ', ' '] print(re.findall("\S","akjfakj cfjak akjf")) #['a', 'k', 'j', 'f', 'a', 'k', 'j', 'c', 'f', 'j', 'a', 'k', 'a', 'k', 'j', 'f'] print(re.findall("\w","qjjqkj12324jfjaj.afja qjj")) #['q', 'j', 'j', 'q', 'k', 'j', '1', '2', '3', '2', '4', 'j', 'f', 'j', 'a', 'j', 'a', 'f', 'j', 'a', 'q', 'j', 'j'] print(re.findall("\W","qkjq?qjk\qkj")) #['?', '\\'] #注意,这里之所以会匹配到两个\\,后面会说到
这里对上面会出现两个\\做个解释
如上图,由于python解释器对\也有转译功能,当我们用正则匹配的时候,先是将命令交给python解释器,然后python解释器再将命令传递给re模块,返回同样道理,但由于\在python解释器这一层也有转译功能,所以在还没传递到re模块时候,命令已经按照python解释器这一层方法进行转译了,所以如果我们想让python解释器将命令原封不动的传递给re模块处理,在匹配规则前面加上r,或者在\前面加\,在python这一层处理完传递到re模块就剩一个\了
元字符之分组()
无名分组:
1 import re 2 m = re.findall(r'(ad)+', 'add') #()相当于将ad看成一个元素进行匹配 3 print(m)#['ad']
有名分组: 格式(?P<name>规则)
1 import re 2 res = re.search("(?P<name>\d+)","jfaj123jlkjfa").group("name")#search查找的结果是一组对象,可以用.group取出结果
3 print(res)#123
re模块下常用方法
1 import re 2 #1 3 re.findall('a','alvin yuan') #返回所有满足匹配条件的结果,放在列表里 4 #2 5 re.search('a','alvin yuan').group() #函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以 6 # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。 7 8 #3 9 re.match('a','abc').group() #同search,不过尽在字符串开始处进行匹配 10 11 #4 12 ret=re.split('[ab]','abcd') #先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割 13 print(ret)#['', '', 'cd'] 14 15 #5 16 ret=re.sub('\d','abc','alvin5yuan6',1) 17 print(ret)#alvinabcyuan6 18 ret=re.subn('\d','abc','alvin5yuan6') 19 print(ret)#('alvinabcyuanabc', 2) 20 21 #6 22 obj=re.compile('\d{3}') 23 ret=obj.search('abc123eeee') 24 print(ret.group())#123 25 1 26 2 27 3 28 4 29 5 30 6 31 import re 32 ret=re.finditer('\d','ds3sy4784a') 33 print(ret) #<callable_iterator object at 0x10195f940> 34 35 print(next(ret).group()) 36 print(next(ret).group())
注意:在有分组元字符()存在时,findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可,格式(?:规则)
1 import re 2 3 ret=re.findall('www.(baidu|oldboy).com','www.oldboy.com') 4 print(ret)#['oldboy'] 5 6 ret=re.findall('www.(?:baidu|oldboy).com','www.oldboy.com') 7 print(ret)#['www.oldboy.com']