CDA数据分析师 出品
在前面一篇文章中,我们主要讲解了re模块中比较简单的两种方法——re.match()与re.search(),也讲解了元字符和限定符这两种在正则表达式中最常用的两类符号。
但是这两种方法只能够在字符串中匹配出一个结果出来,如果要匹配多个呢?比如从下面的字符串中把所有的企业名称提取出来:
message=‘企业名称:CDA数据科学研究院\n邮箱:[email protected]\n地址:北京市海淀区厂洼街3号2号楼2-3层\n网址:http://www.cda.cn\n\企业名称:广州就学在线科技有限公司\n邮箱:[email protected] 地址:广州市黄埔区护林路1198号516房\n网址:www.cda.cn’
如果我们要把上面所有的企业名称提取,用re.match()和re.search()方法明显不可以,这时候我们就可以使用re.findall()方法。
re.findall()方法
re.findall()方法顾名思义,就是对整个字符串中搜索所有符合正则表达式的字符串,符合条件的字符串最后以列表来承载,如果没有匹配上符合条件的字符串,返回空列表。
其调用和使用方法跟re.search()等其他方法类似。看下面的例子:
message=‘企业名称:CDA数据科学研究院\n邮箱:[email protected]\n地址:北京市海淀区厂洼街3号2号楼2-3层\n网址:http://www.cda.cn\n\企业名称:广州就学在线科技有限公司\n邮箱:[email protected]\n地址:广州市黄埔区护林路1198号516房\n网址:www.cda.cn’
pattern=‘企业名称:.*’
re.findall(pattern,message)
Out:[‘企业名称:CDA数据科学研究院’, ‘企业名称:广州就学在线科技有限公司’]
我们发现,re.findall()把两个匹配成功的字符串都提取出来,作为列表的两个元素来返回。
选择字符
如果我们既要提取企业名称,也要提取对应的邮箱,该怎么提取呢?有没有类似条件判断中的"or"选项?有的,这个时候可以使用选择字符"|",比如:
pattern=‘企业名称.|邮箱.’
message=‘企业名称:CDA数据科学研究院\n邮箱:[email protected]\n地址:北京市海淀区厂洼街3号2号楼2-3层\n网址:http://www.cda.cn\n\企业名称:广州就学在线科技有限公司\n邮箱:[email protected]\n地址:广州市黄埔区护林路1198号516房\n网址:www.cda.cn’
findall = re.findall(pattern, message)
print(findall)
Out: [‘企业名称:CDA数据科学研究院’, ‘邮箱:[email protected]’, ‘企业名称:广州就学在线科技有限公司’, ‘邮箱:[email protected]’]
如此类推,如果想要将企业名称、邮箱、地址都一一提取到列表中,只需要在上面模式字符串后面再加上"|地址"即可:
pattern=‘企业名称.|邮箱.|地址.*’
message=‘企业名称:CDA数据科学研究院\n邮箱:[email protected]\n地址:北京市海淀区厂洼街3号2号楼2-3层\n网址:http://www.cda.cn\n\企业名称:广州就学在线科技有限公司\n邮箱:[email protected]\n地址:广州市黄埔区护林路1198号516房\n网址:www.cda.cn’
findall = re.findall(pattern, message)
print(findall)
Out: [‘企业名称:CDA数据科学研究院’, ‘邮箱:[email protected]’, ‘地址:北京市海淀区厂洼街3号2号楼2-3层’, ‘企业名称:广州就学在线科技有限公司’, ‘邮箱:[email protected]’, ‘地址:广州市黄埔区护林路1198号516房’]
匹配某类字符
如果想要提取特定的字符,比如上面message中的"@"、":"、".",该如何单独提取出来?对于这种情况,用列表把你想要提取的字符放进去即可,比如下面的例子:
pattern=’[@:.]’
message=‘企业名称:CDA数据科学研究院\n邮箱:[email protected]\n地址:北京市海淀区厂洼街3号2号楼2层\n网址:http://www.cda.cn\n\企业名称:广州就学在线科技有限公司\n邮箱:[email protected]\n地址:广州市黄埔区护林路1198号516房\n网址:http://www.cda.cn\n’
findall = re.findall(pattern, message)
print(findall)
Out: [’:’, ‘:’, ‘@’, ‘.’, ‘:’, ‘:’, ‘.’, ‘.’, ‘:’, ‘:’, ‘@’, ‘.’, ‘:’, ‘:’, ‘.’, ‘.’]
当然,单独提取这些符号没有多大意义,如果我们希望匹配的是这些符号后面对应的字符呢?我们可以在模式字符串中的列表后面添加元字符和限定符:
pattern=’[@:.].*’
message=‘企业名称:CDA数据科学研究院\n邮箱:[email protected]\n地址:北京市海淀区厂洼街3号2号楼2层\n网址:http://www.cda.cn\n\企业名称:广州就学在线科技有限公司\n邮箱:[email protected]\n地址:广州市黄埔区护林路1198号516房\n网址:http://www.cda.cn\n’
findall = re.findall(pattern, message)
print(findall)
Out: [’:CDA数据科学研究院’, ‘:[email protected]’, ‘:北京市海淀区厂洼街3号2号楼2层’, ‘:www.cda.cn’, ‘:广州就学在线科技有限公司’, ‘:[email protected]’, ‘:广州市黄埔区护林路1198号516房’, ‘:www.cda.cn’]
同理,上一节最后提取企业名称、邮件、地址的例子,我们可以写成下面这样的方式:
pattern=’[企邮地].*’
message=‘企业名称:CDA数据科学研究院\n邮箱:[email protected]\n地址:北京市海淀区厂洼街3号2号楼2-3层\n网址:http://www.cda.cn\n\企业名称:广州就学在线科技有限公司\n邮箱:[email protected]\n地址:广州市黄埔区护林路1198号516房\n网址:www.cda.cn’
findall = re.findall(pattern, message)
print(findall)
Out: [‘企业名称:CDA数据科学研究院’, ‘邮箱:[email protected]’, ‘地址:北京市海淀区厂洼街3号2号楼2-3层’, ‘企业名称:广州就学在线科技有限公司’, ‘邮箱:[email protected]’, ‘地址:广州市黄埔区护林路1198号516房’]
上面模式字符串的写法相当于匹配以"企"、“邮”、"地"开头的字符,以及后续的字符串,一直到换行符才结束匹配。
这类的模式字符串还经常用于匹配某类型的字符,比如匹配文本里面所有的汉字,我们可以将模式字符串写成’[\u4e00-\u9fa5]+’,比如:
pattern=’[\u4e00-\u9fa5]+’
message='企业名称:CDA数据科学研究院\n邮箱:[email protected]\n地址:北京市海淀区厂洼街3号2号楼2层\n网址:http://www.cda.cn\n\
企业名称:广州就学在线科技有限公司\n邮箱:[email protected]\n地址:广州市黄埔区护林路1198号516房\n网址:http://www.cda.cn\n’
findall = re.findall(pattern, message)
print(findall)
Out: [‘企业名称’, ‘数据科学研究院’, ‘邮箱’, ‘地址’, ‘北京市海淀区厂洼街’, ‘号’, ‘号楼’, ‘层’, ‘网址’, ‘企业名称’, ‘广州就学在线科技有限公司’, ‘邮箱’, ‘地址’, ‘广州市黄埔区护林路’, ‘号’, ‘房’, ‘网址’]
匹配文本中所有的数字,可以写成’[0-9]+’ ,比如:
pattern=’[0-9]+’
message='企业名称:CDA数据科学研究院\n邮箱:[email protected]\n地址:北京市海淀区厂洼街3号2号楼2层\n网址:http://www.cda.cn\n\
企业名称:广州就学在线科技有限公司\n邮箱:[email protected]\n地址:广州市黄埔区护林路1198号516房\n网址:http://www.cda.cn\ng’
findall = re.findall(pattern, message)
print(findall)
Out: [‘1918560461’, ‘3’, ‘2’, ‘2’, ‘981856661’, ‘1198’, ‘516’]
当然,直接使用元字符"\d"来匹配所有数字也是一样:
pattern=’\d+’
message=‘企业名称:CDA数据科学研究院\n邮箱:[email protected]\n地址:北京市海淀区厂洼街3号2号楼2层\n网址:http://www.cda.cn\n\企业名称:广州就学在线科技有限公司\n邮箱:[email protected]\n地址:广州市黄埔区护林路1198号516房\n网址:http://www.cda.cn\ng’
findall = re.findall(pattern, message)
print(findall)
Out: [‘1918560461’, ‘3’, ‘2’, ‘2’, ‘981856661’, ‘1198’, ‘516’]
再比如匹配文本内所有的小写英文字幕:
pattern=’[a-z]+’
message='企业名称:CDA数据科学研究院\n邮箱:[email protected]\n地址:北京市海淀区厂洼街3号2号楼2层\n网址:http://www.cda.cn\n\
企业名称:广州就学在线科技有限公司\n邮箱:[email protected]\n地址:广州市黄埔区护林路1198号516房\n网址:http://www.cda.cn\n’
findall = re.findall(pattern, message)
print(findall)
Out: [‘qq’, ‘com’, ‘www’, ‘cda’, ‘cn’, ‘qq’, ‘com’, ‘www’, ‘cda’, ‘cn’]
这里为大家整理一下这类常用的模式字符串写法:
· 如果是匹配文本内所有大写英文单词,模式字符串可以写成’[A-Z]+’
· 如果是匹配文本内所有大写、小写英文单词,模式字符串可以写成’[aA-zZ]+’
· 如果是匹配文本内所有大小写英文单词以及数值串,模式字符串可以写成’[a0-z0-9A-Z]+’