当有一段文本,需要提取其中的指定数据,可用正则表达式解决。例如,提取文中的手机号和邮箱
text=’哈哈哈能达到我FIFO哦亲,手机号15917971566,微风轻拂i祈福祈福哈哈哈能达到我FIFO哦亲,手机号15917971566,微风轻拂i祈福祈福哈哈哈能达到我FIFO哦亲,手机号15917971566,微风轻拂i祈福祈福哈哈哈能达到我FIFO哦亲,手机号15917971566,微风轻拂i祈福祈福哈哈哈能达到我FIFO哦亲,手机号15917971566,微风轻拂i祈福祈福‘
正则表达式——从一段文本中提取一段符合相应格式数据
1.1.1正则表达式
1.字符相关
TeaDrinkingGong
匹配文本中的TeaDrinkingGong
import re
text='王府i额发布i本文分为覅TeaDrinkingGong'
data_list=re.findall('TeaDrinkingGong',text)
print(data_list)#['TeaDrinkingGong']
[abc]
匹配a或b或c字符
import re
text='weggwgq2afafgscbwewhw'
data_list=re.findall('[abc]',text)
print(data_list)#['a', 'a', 'c', 'b']
也可以在前面加上其他修饰
import re
text='weggwgq2afafgscbwewhw'
data_list=re.findall('f[abc]',text)
print(data_list)#['fa']
[^abc]
匹配除了abc以外的字符
import re
text='weggwgq2afafgscbwewhw'
data_list=re.findall('^[abc]',text)
print(data_list)#['w', 'e', 'g', 'g', 'w', 'g', 'q', '2', 'f', 'f', 'g', 's', 'w', 'e', 'w', 'h', 'w']
[a-z]
匹配a到z任意一个字符
import re
text='weggwgq2afafgscbwewhw'
data_list=re.findall('f[a-z]',text)
print(data_list)#['fa', 'fg']
.
带指除换行符之外任意字符,但只能代表一个字符
import re
text='weggwgq2afafgscbwewhw'
data_list=re.findall('f.s',text)
print(data_list)#['fgs']
import re
text='weggwgq2afafgscbwewhw'
data_list=re.findall('f.+s',text)#贪婪匹配,越长越好
print(data_list)#['fgs']
import re
text='weggwgq2afafgscbwewhw'
data_list=re.findall('f.+?s',text)#非贪婪匹配
print(data_list)#['fgs']
\w
代指数字或字母或下划线(汉字)
import re
text='不玩ifggw威 锋qf网wfwf我不玩qwf'
data_list=re.findall('不\w+w',text)
print(data_list)#['不玩ifggw', '不玩qw']
\d
代表整数
import re
text='ewfd2ff497wgwd85fwqwgd6'
data_list=re.findall('d\d',text)
print(data_list)#['d2', 'd8', 'd6']
- \s代指任意空白符,包括空格制表符
import re
text='ewfd 2ff49 7w gwd85fw qwgd6'
data_list=re.findall('w\s\w+w',text)
print(data_list)#
2.字符相关
*
重复0次或多次
import re
text='他是大B个,确实是个大2B'
data_list=re.findall('大2*B',text)
print(data_list)#['大B', '大2B']
-
+
重复1次或多次 -
?
重复0次或1次 -
{n}
重复n次 -
{n,}
重复n次或更多次 -
{n,m}
重复n到m次
3.括号(分组) -
提取数据区域
import re
text='手机号16992758201tel18520205819'
data_list=re.findall('1699(2\d{5})',text)
print(data_list)#['275820']
import re
text='手机号16992658201tel16992666666'
data_list=re.findall('16(99)2(6\d{5})',text)
print(data_list)#[('99', '658201'), ('99', '666666')]
import re
text='手机号16992758201tel18520205819'
data_list=re.findall('1699(2\d{5})',text)
print(data_list)#['275820']
- 获取指定区域+或条件
利用|
即可
练习题
1.利用正则表达式匹配QQ号
[1-9]\d{4,}
2.身份证
import re
text='def130429191912015219k13042919591219521Xkk'
data_list=re.findall('\d{17}[\dX]',text)#与之前的[abc]类似
print(data_list)#['130429191912015219', '13042919591219521X']
import re
text='def130429191912015219k13042919591219521Xkk'
data_list=re.findall('\d{17}(\d|X)',text)#利用|来选择,但是会舍弃前面的号码
print(data_list)#['9', 'X']
import re
text='def130429191912015219k13042919591219521Xkk'
data_list=re.findall('(\d{17}(\d|X))',text)#为防止刚刚情况发生,在整个外面再套一个大括号
print(data_list)#[('130429191912015219', '9'), ('13042919591219521X', 'X')]
import re
text='def130429191912015219k13042919591219521Xkk'
data_list=re.findall('(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)',text)#提取身份证中的各项数据
print(data_list)#[('130429', '1919', '12', '01', '521', '9'), ('130429', '1959', '12', '19', '521', 'X')]
3.手机号
import re
text='手机号15009876289,你的14718941'
data_list=re.findall('1[3-9]\d{9)',text)#提取手机号
print(data_list)#['15009876289']
4.邮箱地址
import re
text='邮箱 15009876289@qq.com,你的 wefwgwwf@wenfiw.com'
data_list=re.findall('\w+@\w+.\w+',text)#提取邮箱
print(data_list)#['15009876289@qq.com', 'wefwgwwf@wenfiw.com']
3.起始和结束
上述示例中都是匹配文本中一段文字,只要其中存在即可,但如果要求用户输入内容必须是指定内容开头和结尾,就需要用到以下两个字符。
^
起始$
结束
import re
text='邮箱15009876289@qq.com呵呵'
email=re.findall('^\w+@\w+.\w+$',text,re.ASCII)#提取邮箱号,其中字符使用ASCII编码
print(email)#[]
import re
text='15009876289@qq.com'
email=re.findall('^\w+@\w+.\w+$',text,re.ASCII)#提取邮箱号,其中字符使用ASCII编码
print(email)#['15009876289@qq.com']
这种一般用于用户输入校验较多
import re
text=input('请输入邮箱')
email=re.findall('^\w+@\w+.\w+$',text,re.ASCII)#提取邮箱号,其中字符使用ASCII编码
if not email:
print('邮箱格式错误')
else:
print(email)
4.特殊字符
由于正则表达式中* . \ { } ( )
均有特殊含义,需要转义
import re
text='我是你{5}爸爸'
data=re.findall('你{5}爸',text)#提取邮箱号,其中字符使用ASCII编码
print(data)#[]
import re
text='我是你{5}爸爸'
data=re.findall('你\{5\}爸',text)#提取邮箱号,其中字符使用ASCII编码
print(data)#['你{5}爸']
5.re模块
python中提供了re模块,可处理正则表达式并进行处理
- findall,获取匹配到的所有数据
import re
text='def130429191912015219k13042919591219521Xkk'
data=re.findall('\d{17}[\dX]',text)#与之前的abd类似[abc]
print(data)#['130429191912015219', '13042919591219521X']
- match,从起始位置开始匹配,成功返回一个对象,不成功则返回None
import re
text='分区夫妻感情gw啊父亲'
data=re.match('情\ww',text)
print(data)#None
import re
text='情gw啊父亲分区夫妻感'
data=re.match('情\ww',text)
if data:
print(data.group())#情gw
- search,匹配整个字符串出现的第一个,成功返回一个对象,不成功则返回None
import re
text='分区夫妻感情gw啊父亲'
data=re.match('情\ww',text)
if data:
print(data.group())#情gw
- sub,替换匹配成果的位置
import re
text='潜伏期为全国4t给我跟我哥42'
data=re.sub('4\w','五分',text)
print(data)#潜伏期为全国五分给我跟我哥五分
同时可指定位置替换,其余则不替换
import re
text='潜伏期为全国4t给我跟我哥42'
data=re.sub('4\w','五分',text,1)
print(data)#潜伏期为全国五分给我跟我哥42
- split,根据匹配成果的位置分割
import re
text='潜伏期为全国4t给我跟我哥42'
data=re.split('4\w',text)
print(data)#['潜伏期为全国', '给我跟我哥', '']
可传上参数说明第几个分割
import re
text='潜伏期为全国4t给我跟我哥42'
data=re.split('4\w',text)
print(data)#['潜伏期为全国', '给我跟我哥42']
finditer
,与findall
类似,但返回的是一个迭代器,循环一次才返回一次
import re
text='def130429191912015219k13042919591219521Xkk'
data=re.finditer('\d{17}[\dX]',text)
for item in data:
print(item.group())
#130429191912015219
#13042919591219521X
正则:命名分组(正则),(?P<名称>正则)
可与finditer
获取分组
import re
text='def130429191912015219kasd13042919191201521Xkk'
data=re.finditer('\d{6}(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2})\d{3}\d|X',text)
for item in data:
print(item.groupdict())
#{'year': '1919', 'month': '12', 'day': '01'}