一、主要正则表达式
图1 正则表达式主要内容总结
二、正则类型
1、查找
①表达式:re.findall(pattern, string, flags)
其中pattern为正则表达式,string为待查找字符串,flags为图一中所述的模式
②查找结果以列表的形式返回
2、替换
①表达式:re.sub(pattern, repl, string, count, flags)
其中pattern、string及flags与查找含义一致;count代表查找后最大被替换次数,默认值为0,且设定
0为全部替换
例:
import re
language = 'PythonC#JavaC#PHPC#'
r = re.sub('C#', 'GO', language, 1)
print(r)
输出结果为:
PythonGOJavaC#PHPC#
②值得注意的事,sub中的repl还可以是函数,例:
import re
def convert(value):
pass
lanuage = 'PythonC#JavaC#PHPC#'
r = re.sub('C#', convert, lanuage, 1)
print(r)
输出结果为:
PythonJavaC#PHPC#
那么,value到底是什么东西呢?会是字符串‘C#’吗?
import re
def convert(value):
print(value)
lanuage = 'PythonC#JavaC#PHPC#'
r = re.sub('C#', convert, lanuage, 1)
此时输出结果为:
<re.Match object; span=(6, 8), match='C#'>
我们可以看到这是一个对象,其中span为元组,其中的6代表被替换字符串前有6个字符,8代表被替
换字符最后一位在8号位,即被替换字符串占据了7、8号位;match为被替换元素,可以使用
value.group()得到该值。
总结:python在找到被替换字符串时会将其以对象的形式传入reply函数中,并用repl
函数的返回值替换pattern,默认返回值为None。此外,函数的传入参数也可以是函数!
那么repl可以为函数的好处是什么呢?我们可以动态处理查找到的字符,也就是我们可以依据传入
值的不同对其进行不同的替换操作,下面给出一个例子方便大家理解
我们要实现如下功能:将字符串中大于等于6的数字全部替换为9,小于6的数字全部替换为0(注
意,这种数字是字符形式的数字,而非数值类型的数字,故下面的代码用到了强制转换符int())
当然,对于这种简单的替换可以使用for循环,但是如果替换规则便复杂周,如替换连续的数字,用
for循环处理将会很复杂,下面介绍用正则表达式解决该类问题
import re
def convert(value):
matched = value.group()
if int(matched) >= 6:
return '9'
else:
return '0'
s = 'A8C3721D86'
r = re.sub('\d', convert, s)
print(r)
输出结果为:
A9C0900D99
注意!返回值应该钥匙字符串形式,不能为数值类型!
三、补充
①补充1:match、search函数
match尝试从字符串的首字母开始匹配,找到一个立马返回,若没有找到则返回None;search是搜
索目标字符串,一旦 找到立马返回,故至多返回一个结果,可用来判断某个字符串是否有pattern; 例:
import re
s = 'A8C3721D86'
r = re.match('\d',s)
r1 = re.search('\d',s)
print("match的结果为:")
print(r)
print("search的结果为:")
print(r1)
输出结果为:
match的结果为:
None
search的结果为:
<re.Match object; span=(1, 2), match='8'>
我们发现,match的返回结果为None,因为s的首字母不是数字;此外,search与match的返回结果
都为对象!(match返回结果请自行检验),这与findall(列表)以及sub(字符串)不同,我们可以用正
则表达式内置的对象方法group()调用搜索结果(与前面讲sub时所列举的convert函数种的调用一致)
②补充2:span()与group(group1, group2,…)方法
span()与group()方法都为re模块内置类的实例方法,具体作用前面已经提到,但是group()方法的应用
范围很广,尤其是在爬虫中经常使用,在此深入地讲解。
我们先看看以下示例,我们想得到life和python中间的所有字符:
s = 'life is short, i use python '
r = re.search('life.*python ', s) # 普通字符起定界作用
print(r.group())
输出结果为
life is short, i use python
大家可能觉得group作用不大,因为此时只有一个分组(组的概念见上面图1),我们做如下改变
r = re.search('life(.*)python ', s)
结果怎么还是一样?因为r.group()默认为r.group(0),0始终代表所匹配到的整个字符串,如果我们想
遍历分组,则应该从1开始,将其改为
print(r.group(1))
输出结果为:
is short, i use
我们成功地得到了想要的结果
但是我们其实可以直接用findall快速找到与此一样的结果,代码如下:
r = re.findall('life(.*)python ', s)
所以一般不推荐使用match和search,推荐使用findall