1. re模块中常用到的函数
1.1 search:执行正则表达式搜索并且在搜索结束后返回所匹配到的串,只返回第一次匹配到的结果
.group()是_sre.SRE_Match的属性,也就是说只有_sre.SRE_Match才能调用group( )
a = re.search("\d+", "呵呵哈哈8786你干什么")
print(a)
print(a.group())
运行结果:
<_sre.SRE_Match object; span=(4, 8), match='8786'>
8786
1.2 findall:匹配所有的对象,返回一个列表。
a = re.findall("\d", "123654789")
print(a)
运行结果
['1', '2', '3', '6', '5', '4', '7', '8', '9']
1.3 sub:实现替换
a = re.sub("共产党", "****", "中国共产党万岁")
print(a)
运行结果
中国****万岁
1.4 split:分割字符串,返回解过列表
a = re.split("\.", "www.qq.com")
print(a)
运行结果
['www', 'qq', 'com']
1.5 finditer:匹配所有对象返回一个迭代器
a = re.finditer("\d{3}", "asd654a645f6s543f")
for i in a:
print(i)
运行结果
<_sre.SRE_Match object; span=(3, 6), match='654'>
<_sre.SRE_Match object; span=(7, 10), match='645'>
<_sre.SRE_Match object; span=(13, 16), match='543'>
1.6 compile:compile用来编译正则表达式模式字符串,并生成Regular Expression Objects
t = "Lixiaolong"
p = re.compile("li.*", re.I)
print(p.match(t))
运行结果
<_sre.SRE_Match object; span=(0, 10), match='Lixiaolong'>
2. 分组
如果想把区号从匹配的电话号码中分离,可以添加括号在正则表达式中创建分组,再使用group()方法,从一个分组中获取匹配的文本。正则表达式字符串中,第一个括号是第一组,第二个括号是第二组。向group()方法传入参数1或2,可以获得匹配文本中的不同部分,传入0或者不传参数,将返回整个匹配的文本。
2.1 比如说获得一个电话号码的区号
r = re.search("(\d{4})-(\d{8})", "我的电话号码是0371-56678888")
print(r)
print(type(r))
print(r.group())
print(type(r.group()))
运行结果是
<_sre.SRE_Match object; span=(7, 20), match='0371-56678888'>
<class '_sre.SRE_Match'>
0371-56678888
<class 'str'>
使用groups()方法可以返回包含所有分组的元组
r = re.search("(\d{4})-(\d{8})", "我的电话号码是0371-56678888")
print(r.groups())
print(type(r.groups()))
print(r.group(1))
print(r.group(2))
运行结果
('0371', '56678888')
<class 'tuple'>
0371
56678888
3. 捕获性括号( )和非捕获性括号(?: )
注意下面这些例子都是出现在有或( | )的时候。
首先看下面这个例子,我们想匹配"452168"和"452183",先用match函数
t1 = "452183"
t2 = "452168"
r1 = re.match("\d+(183|168)", t1)
r2 = re.match("\d+(183|168)", t2)
print(r1)
print(r2)
运行结果
<_sre.SRE_Match object; span=(0, 6), match='452183'>
<_sre.SRE_Match object; span=(0, 6), match='452168'>
再用findall函数
t1 = "452183"
t2 = "452168"
r1 = re.findall("\d+(183|168)", t1)
r2 = re.findall("\d+(183|168)", t2)
print(r1)
print(r2)
发现运行结果如下
['183']
['168']
明显没有达到预期结果
修改一下
t1 = "452183"
t2 = "452168"
r1 = re.findall("\d+(?:183|168)", t1)
r2 = re.findall("\d+(?:183|168)", t2)
print(r1)
print(r2)
发现结果如下
['452183']
['452168']
这是为什么呢?
下面来看一个例子
print(re.findall("\d+(183)\d+", "123183123"))
print(re.findall("\d+(183)\d+(168)\d+", "123183123168123"))
运行结果如下
['183']
[('183', '168')]
大家再下面这个程序
print(re.findall("\d+(?:183)\d+(?:168)\d+", "123183123168123"))
运行结果如下
['123183123168123']
因为在正则表达式里,( )的内容会被捕获,其他的内容不会被捕获,而(?: )带有这样的括号内容都会被捕获。
4. 正则的贪婪和懒惰
在python中正则表达式默认是贪婪模式,贪婪模式的正则表达式总会尽可能多的匹配更多的字符
这是贪婪模式的正则表达式
print(re.match("this.*", "this a desk"))
运行结果
<_sre.SRE_Match object; span=(0, 11), match='this a desk'>
下面我们用?关闭贪婪模式,开启懒惰模式
print(re.match("this.*?", "this a desk"))
程序运行结果如下
<_sre.SRE_Match object; span=(0, 4), match='this'>