正则表达式和re模块
什么是正则表达式
通俗理解:按照一定的规则,从某个字符串中匹配出想要的数据。这个规则就是正则表达式。
标准答案:https://baike.baidu.com/item/正则表达式/1700215?fr=aladdin
一个段子:
世界是分为两种人,一种是懂正则表达式的,一种是不懂正则表达式的。
1.正则表达式的常用规则
1.1 匹配某个字符串
import re
text='hello'
ret=re.match('he',text)#只拿到开始进行匹配
print(ret.group())
1.2 点(.)匹配任意的字符
import re
text='hello'
ret=re.match('.',text)#只能匹配一个字符
print(ret.group())
但是点(.)匹配不到换行符
import re
text='\na'
ret=re.match('.',text)
print(ret.group())
结果显示'NoneType' object has no attribute 'group'
1.3 \d匹配任意的数字
import re
text='1na'
ret=re.match('\d',text)
print(ret.group())
1.4 \D匹配任意的非数字
import re
text='hello'
ret=re.match('\D',text)
print(ret.group())
1.5 \s匹配空白字符(\n,\t,\r,空格)
import re
text=' hello'
ret=re.match('\s',text)
print(ret.group())
1.6 \w匹配a-z和A-Z以及数字和下划线
import re
text='hello'
ret=re.match('\w',text)
print(ret.group())
1.7 \W和\w匹配的是相反的
import re
text='+hello'
ret=re.match('\W',text)
print(ret.group())
1.8 []组合的方式,只要出现在中括号中的,就可以匹配
import re
text='+hello'
ret=re.match('[+2]',text)
print(ret.group())
可以把前边的几种形式添加到[]中
import re
text='3117-09000808'
ret=re.match('[\d\-]',text)#第2个\是转义字符,因为-是特殊字符
print(ret.group())
如果想要匹配到整个字符串中前边满足条件的所有字符,需要在[]后加+,示例如下:
import re
text='3117-09000808'
ret=re.match('[\d\-]+',text)
print(ret.group())
1.9 之前提到的几种匹配规则,其实可以用[]的方式代替
中括号的形式代替\d
import re
text='09'
ret=re.match('[0-9]',text)
print(ret.group())
中括号的形式代替\D
import re
text='_09'
ret=re.match('[^0-9]',text)
print(ret.group())
中括号的形式代替\w
import re
text='_09'
ret=re.match('[_0-9a-zA-Z]',text)
print(ret.group())
中括号的形式代替\W
import re
text='+_09'
ret=re.match('[^_0-9a-zA-Z]',text)
print(ret.group())
2.匹配多个字符
2.1 '*':可以匹配0个或任意多个字符
import re
text='311709000808'
ret=re.match('\d*',text)
print(ret.group())
即使是非数字也不会报错,匹配到0个
2.2 '+':匹配一个或多个字符
import re
text='abcd'
ret=re.match('\w+',text)
print(ret.group())
如果text='+abcd'会报错
2.3 '?':匹配一个或零个(要么没有,要么就只会匹配到一个)
import re
text='abcd'
ret=re.match('\w?',text)
print(ret.group())
# import re
# text='+abcd'
# ret=re.match('\w?',text)
# print(ret.group())
2.4 {m}:匹配m个字符
import re
text='abcd'
ret=re.match('\w{2}',text)
print(ret.group())
2.5 {m,n}:匹配m-n个字符(最多能匹配几个,就匹配几个)
#实例中text中最多有4个字符,就匹配4个
import re
text='abcd'
ret=re.match('\w{1,5}',text)
print(ret.group())
# import re
# text='abcdab'
# ret=re.match('\w{1,5}',text)
# print(ret.group())
3.小案例
3.1 验证手机号码:手机号码的规则是以1开头,第二位可以是34587,后边那9为随意
import re
text='18523399401'
ret=re.match('1[34587]\d{9}',text)
print(ret.group())
3.2 验证邮箱:前边是字母、下划线或者数字,然后是@符号,数字或小写英文字符,'.',最后是英文字符
import re
text='trytofly_12@qq.com'
ret=re.match('\w+@[0-9a-z]+\.[a-z]+',text)
print(ret.group())
3.3 验证URL:前面是http或https或者是ftp然后再加上一个冒号,再加上两个斜杠,最后可以出现任意多个非空白字符
import re
text='https://mp.csdn.net/'
ret=re.match('(http|https|ftp)://[^\s]+',text)
print(ret.group())
3.4 验证身份证:总共有18位,前边17位是数字,最后一位可以是数字,也可以是小写的x,也可以是大写的X
import re
text='15245648979496418x'
ret=re.match('\d{17}[\dxX]',text)
print(ret.group())
#前边那种其实是错误的,最后没有控制长度
#import re
#text='15245648979496418x'
#ret=re.match('\d{17}[\dxX]$',text)
#print(ret.group())
4.正则表达式之开始结束和或语法
4.1 ^:表示以……开始
import re
text='hello'
ret=re.match('^h',text)
print(ret.group())
# 其实这里的^并没有意义,因为match是从头开始匹配,只要第一个字母不是'h'就无法匹配成功
# import re
# text='hello'
# ret=re.match('h',text)
# print(ret.group())
# 但如果是search函数,它在text中寻找'o',如果前边加^,'o'就必须是在第一个字母位置
# import re
# text='hello'
# ret=re.search('o',text)
# print(ret.group())
# 如果是下边这样就会失败
# import re
# text='hello'
# ret=re.search('^o',text)
# print(ret.group())
^在中括号中代表取反操作
4.2 $:表示以……结尾
假如邮箱必须以@163.com结尾,示例如下:
import re
text='trytofly@163.com'
ret=re.match('\w+@163.com$',text)
print(ret.group())
4.3 |:匹配提供多种开头的选择
import re
text='http'
ret=re.match('http|https|ftp',text)
print(ret.group())
4.4 贪婪模式与非贪婪模式
#贪婪模式匹配尽量多的字符
import re
text='0123456'
ret=re.search('\d+',text)
print(ret.group())
#贪婪模式匹配尽量少的字符
import re
text='0123456'
ret=re.match('\d+?',text)
print(ret.group())
再看一个例子
#贪婪模式
import re
text='<h1>标题</h1>'
ret=re.match('<.+>',text)
print(ret.group())
#非贪婪模式
import re
text='<h1>标题</h1>'
ret=re.match('<.+?>',text)
print(ret.group())
例2:匹配0-100之间的数字
#可以出现0,1,2,3,99,100
#不可以出现09,101,1000,0
import re
text='0'
ret=re.match('[1-9]\d?$|100$|0$',text)
print(ret.group())
5.转义字符和原生字符串
5.1 转义字符串
在正则表达式中,有些字符是有特殊意义的字符。因此如果想要匹配这些字符,那么就必须使用反斜杠进行转义。比如$代表的是以……结尾,如果想要匹配$,就必须使用\$,示例如下:
匹配苹果的价格
import re
text='apple price is $299'
ret=re.search('\$\d+',text)
print(ret.group())
5.2 原生字符串
在正则表达式中,\是专门用来做转义的。在python中\也是用来做转义的,因此想要在普通的字符串中匹配出\,那么要匹配出4个\,但用原生字符串只需要2个,示例如下:
import re
text='\c'
#匹配'\c'的两种方法
#1.转义
# python中:\\\\c->\\c
# 正则表达式中:\\c->\c
res=re.match('\\\\c',text)
#2.原生字符串
#python中:\\c->\\c
res=re.match(r'\\c',text)
print(res.group())
6.正则表达式之group分组
在正则表达式中,可以对过滤到的元素进行分组,分组使用圆括号的方式
import re
text="apple's price is $299,orange's price is $10"
res=re.match('.*(\$\d+).*(\$\d+)',text)
#整个正则表达式是一个外边大的分组,0写和不写意思一样
print(res.group(0))
#取到第一个分组
print(res.group(1))
#取到第二个分组
print(res.group(2))
#取到所有的子分组
print(res.groups())
7.正则表达式之re常用模块
7.1 findall:找出所有满足条件的,返回的是一个列表
import re
text="apple's price is $299,orange's price is $10"
res=re.findall('\$\d+',text)
print(res)
7.2 sub:用来替换字符串,将匹配到的字符串替换为其它字符串
import re
text="apple's price is $299,orange's price is $10"
res=re.sub('\$\d+','0',text,1)#第4个参数为要替换几个
print(res)
7.3 split:使用正则表达式来分割字符串,以列表形式返回
import re
text="hello world try to fly"
res=re.split(' ',text)
print(res)
7.4 compile:对于一些经常要用到的正则表达式,可以使用compile进行编译,后期再使用的时候可以直接拿过来用,执行效率会更快,而且compile还可以指定flag=re.VERBOSE,在写正则表达式的时候可以做好注释,示例代码如下:
import re
text="the number is 20.50"
r=re.compile('\d+\.?\d*')
ret=re.search(r,text)
print(ret.group())
方便记忆的方法
import re
text="the number is 20.50"
r=re.compile(r"""
\d+ #小数点前边的数字
\.? #小数点
\d* #小数点后边的数字
""",re.VERBOSE)
ret=re.search(r,text)
print(ret.group())