正则表达式旨在对字符串进行有一定规律的操作,在python中,以re
(Regular Expression)模块来实现。最常用的方法有查找(findall
)、替换(sub
)、切割(split
)
以findall
为例,来看看它的具体参数:
findall(pattern,string,flags=0)
pattern:指定需要匹配的正则表达式
string:指定待处理的字符串
flags:指定匹配模式。常用re.I:不区分大小写
这里pattern
就是正则表达式,它通常是由若干个正则符号组合而成的。下面我们介绍几种常用的正则符号:
1. 原字符
即“要匹配什么,就写什么”
import re
s='''小明,电话:13845459595,学号:12056854747城市:'北京市'
小曾,电话:13748489696,学号:11548685895,城市:'成都市' '''
比如我们想在字符串s中查找出“电话”这个字符:
re.findall("电话",s)
['电话', '电话']
2. (英文状态下的句点)
.
:除换行符(\n)外,可指代任意一个
字符
如我们要查找出以”小“开头且名字为两个字符的姓名:
re.findall("小.",s)
['小明', '小曾']
3. 转义字符
\n
:一个换行符
\t
:一个(Tab)制表符
\d
:0~9中任意一个数字
\s
:指代任意一种空白(空格、制表符、换行符)
\w
:指字母、数字、下划线中的任意一种
\.
:指句点本身
如我们要提取字符串中的电话和学号:
re.findall("\d\d\d\d\d\d\d\d\d\d\d",s)
['13845459595', '12056854747', '13748489696', '11548685895']
这里我们可以提取11位的数字,但是显然非常麻烦,下面我们介绍:
*4.
+
、*
、?
、[]
、()
、{}*
(1)
+
:指匹配1次及以上
(2)*
:指匹配0次及以上
(3)?
:匹配0次或1次
(4)[]
:中括号限定匹配的内容
(5)()
:只输出圆括号中的内容
(6){}
:限定匹配的次数
(1)使用+匹配1次及以上
re.findall("\d+",s)
['13845459595', '12056854747', '13748489696', '11548685895']
(2)*
和+
差不多,不再举例
(3)?
:对字符“s”匹配0次或1次,所以可以找出http和https两种格式:
s='''https://www.baidu.com
http://www.gov.com'''
re.findall("https?://www\..+",s)
['https://www.baidu.com', 'http://www.gov.com']
(4)和(6)提取号码
因为号码都是1开头,第二位必须是3,5,6,7,8,9中的一位,所以在这里使用中括号[ ]
来限定第二位的选取范围:
s='''小明,电话:13845459595,学号:12056854747城市:'北京市'
小曾,电话:13748489696,学号:11548685895,城市:'成都市' '''
re.findall("1[356789]\d+",s)
['13845459595', '13748489696', '1548685895']
然而结果出现了1548685895,这是因为使用了+
(加号)的原因,系统不清楚后面具体要多少位,所以这里还要使用大括号{ }
来限定其位数:
re.findall("1[356789]\d{9}",s)
['13845459595', '13748489696']
这里我们限定\d
的位数为9,刚好符合11位电话号码的要求。
tips:
{8,9}
:表示限定位数为8或9
{8,}
:表示限定位数为8位以上
(5)圆括号可以提取出需要打印的部分,比如我们要提取出字符串中人员所在城市的名称:
re.findall("城市:'.+'",s)
["城市:'北京市'", "城市:'成都市'"]
这里我们虽然提取出来了,但是包含了“城市”,所以我们对城市名加上()
,来指定提取项:
re.findall("城市:'(.+)'",s)
['北京市', '成都市']
.*?
介绍一个常用的正则表达式 .*?
,它可以非贪婪地匹配任意多的字符,如:
s=''''xxIoordgdfxxloveoosffaxxpythonoo' '''
这里有一个字符串,我们想要提取出左边为xx和右边为oo的字符串,这里如果我们使用.*
写法,如下所示:
re.findall("xx(.*)oo",s)
['Ioordgdfxxloveoosffaxxpython']
我们发现,.*
贪婪地将中间所有的字符串都提取了出来,而如我们使用.*?
,如下:
re.findall("xx(.*?)oo",s)
['I', 'love', 'python']
可以看到将所有符合条件的字字符串都提取出来了,这才是我们想要的结果
总结&注意:
+
、*
、?
等正则符号只对其左边的第一个符号起作用- 中括号
[ ]
中一定要充分考虑所有取值可能- sub通常用于删除空白,将其替换为空字符
""
即可(.*?)
非常好用,且经常会用到