在读大学的时候仿佛学过正则表达式(十多年前的事儿),近些年已然全部忘记,这个晦涩难懂的名字能记住就不错了。最近半年我开始发奋图强,在学python的时候看到正则表达式这一章节,学习了半天,题都会做了,也就那样了。后来又开始通过《Linux鸟哥私房菜》复习一下Linux,又看到了正则表达式的身影,发现又都忘记了,哎,又学了一遍。最近又学习Jmeter,又又又看到了正则表达式,当时的心情,就是,这玩意这么重要啊,这么高频出现的技能,可一定要学会记住啊!
在学习python中,通过正则表达式可以进行两方面的工作,一是进行格式是否匹配的验证,二是从log日志或某文档中提取所需字段,如电话号码等。举例如下:
1、假设本地有个文件,内容如下:
姓名:李小二,电话:0431-12345678,居住地:长春
姓名:张晓花,电话:010-80812211,居住地:北京
姓名:李书豪,电话:15932886751,居住地:广州
…
写一段python代码,从文件中提取所有的电话号码
2、分析情况:
由于格式比较统一,我们能分析出来电话号码始终在【电话:】和【,居住地】中间,所以很好提取,python代码如下:
import re
with open(r"I:\python\info.txt",'r') as rf:
text=rf.read()
p2=r"电话:(.*),居住地"
r2=re.findall(p2,text)
print(r2)
3、代码说明:
1)import re导入正则表达式模块。然后open文件,将内容读取到text字符串中。
2)设置正则表达式的样式为: p2=r"电话:(.*),居住地"
目的是选择所有符合p2样式的内容,即左边是“电话”,右边是“,居住地“的所有内容。
其中:
.是正则表达式中的通配符,能匹配任意一个字符。*是指0到多个。.*组合起来就是任意多个字符,即匹配所有字符。
()的意思是,按这个样式匹配的结果中,我只需要()中的内容,去除其他字符。即我只需要电话号码,不需要左边的“电话”和右边的“,居住地“,所以将需要提取的内容用()括起来。
3)使用re模块的findall函数进行匹配,第一个参数为匹配的样式,第二个参数为要匹配的字符串,函数返回的是一个字符串列表,即将所有匹配结果放到list列表中。
4、python执行后的结果是:
[‘0431-12345678’, ‘010-80812211’, ‘0531-56010007’]
5、对于()我感觉说的不明白,可以自己实践一下,
1)若没有括号,p2=r"电话:.*居住地",则结果如下:
[‘电话:0431-12345678,居住地’, ‘电话:010-80812211,居住地’, ‘电话:15932886751,居住地’]
2)若有括号,p2=r"电话:(.*),居住地",则结果如下:
[‘0431-12345678’, ‘010-80812211’, ‘0531-56010007’]
1、还是以上面为例,文件内容还是不变:
姓名:李小二,电话:0431-12345678,居住地:长春
姓名:张晓花,电话:010-80812211,居住地:北京
姓名:李书豪,电话:15932886751,居住地:广州
但是要从中提取所有的固定电话,不要手机号
2、分析情况:
这样的话,就不能通过刚才左边和右边的标志物方式来提取了,因为如果这样,手机号也被取出来了。
再分析,固定电话一般由三部分组成:3位或4位数字,-,8位数字,我们可以利用这个规则进行匹配。代码如下:
import re
with open(r"I:\python\info.txt",'r') as rf:
text=rf.read()
p1=r"\d{3,4}-\d{8}"
r1=re.findall(p1,text)
print(r1)
3、代码说明:
4、python执行后的结果是:
[‘0431-12345678’, ‘010-80812211’]
re模块还有几个特别常用的函数,如:
search函数,在被查找字符串中,按照样式匹配,返回匹配成功的第一个字符串。
match函数,从被查找字符串的第一个字符开始匹配样式。
sub(p1,newstring,text),替换函数,将text中所有符合p1的字符串替换为newstring