什么是正则表达式
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
爬虫为什么要用正则表达式
实际上爬虫主要是从网上爬取数据和从得到的数据中提取数据。因为我们爬取下来了的数据是全部的网页,这些数据很庞大并且很混乱,大部分的东西使我们不关心的,因此我们需要按我们的需要过滤和匹配出来。那么对于文本的过滤或者规则的匹配,最强大的就是正则表达式,是Python爬虫世界里必不可少的工具。
本文使用python内置的re模块来使用正则表达式。
来看下re模块的使用步骤:
1、导入re模块
2、编写正则表达式
3、使用compile函数编译正则表达式返回一个pattern对象。
4、最后使用Pattern对象提供的属性和方法获得信息,根据需要进行其他的操作
下面是 Pattern 对象提供的一些常用方法:
- findall 方法:全部匹配,返回列表
- search 方法:从任何位置开始查找,一次匹配
- match 方法:从起始位置开始查找,一次匹配
- finditer 方法:全部匹配,返回迭代器
- split 方法:分割字符串,返回列表
- sub 方法:替换
1、findall方法
findall(string[, pos[, endpos]]) | re.findall(pattern, string[, flags])
其中,string 是待匹配的字符串,pos 和 endpos 是可选参数,指定字符串的起始和终点位置,默认值分别是 0 和 len (字符串长度)。findall 以列表形式返回全部能匹配的子串,如果没有匹配,则返回一个空列表。
举个简单例子感受下,使用正则表达式获取字符串中的数字内容,如下所示:
import re #导入模块
string = "adc123haha456" #待匹配的字符串
regex =r'\d+' #编写正则表达式 ,\d+ 匹配一个以上数字
pattern = re.compile(regex) #编译正则表达式并返回一个pattern对象
result = pattern.findall(string) #调用pattern对象的findall方法来匹配返回全部能匹配的子串
print(result) #打印匹配结果,如果没有匹配到结果,则返回一个空列表
执行结果:
2、match 方法
match(string[, pos[, endpos]]) | re.match(pattern, string[, flags])
match 方法用于查找字符串的头部(也可以指定起始位置),它是一次匹配,只要找到了一个匹配的结果就返回,而不是查找所有匹配的结果
参数string表示字符串;pos表示下标,pos和endpos的默认值分别为0和len(string);参数flags用于编译pattern时指定匹配模式。
match方法是从字符串的pos下标处起开始匹配pattern,如果pattern结束时已经匹配,则返回一个Match对象;如果匹配过程中pattern无法匹配,或者匹配未结束就已到达endpos,则返回None
举个例子:
import re #导入模块
regex =r'\d+' #编写正则表达式 ,\d+ 匹配一个以上数字
pattern = re.compile(regex) #编译正则表达式并返回一个pattern对象
result = pattern.match('abc123xyz') #从头部开始查找,没有匹配
print(result)
result = pattern.match('abc123xyz',2,8) #从'c'所在位置开始匹配没有匹配
print(result)
result = pattern.match('abc123xyz',3,8) #从'1'的位置开始匹配,正好匹配
print(result) #返回一个matchd对象
print(result.group()) #获得整个匹配的子串
print(result.start()) #打印开始匹配的位置
print(result.end()) #打印匹配结束位置
print(result.span()) #打印开始匹配和结束匹配位置
执行结果:
当匹配成功时返回一个 Match 对象,其中:
- group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group()
- start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
- end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
- span([group]) 方法返回 (start(group), end(group))。
3、search 方法
re.search(string[, pos[, endpos]]) | re.search(pattern, string[, flags])
参数string表示字符串;pos表示下标,pos和endpos的默认值分别为0和len(string));参数flags用于编译pattern时指定匹配模式
search 方法用于查找字符串的任何位置,它也是一次匹配,只要找到了一个匹配的结果就返回,而不是查找所有匹配的结果。
举个例子:
import re #导入模块
regex =r'123' #编写正则表达式
pattern = re.compile(regex) #编译正则表达式并返回一个pattern对象
result = pattern.search("abc123abc123") # 这里如果使用 match 方法则不匹配
print(result)
print(result.group())
print(result.span())
result = pattern.search("abc123abc123",5,12) #指定匹配字符位置
print(result)
print(result.group())
print(result.span())
运行结果:
4、finditer 方法
finditer 方法的行为跟 findall 的行为类似,也是搜索整个字符串,获得所有匹配的结果。但它返回一个顺序访问每一个匹配结果(Match 对象)的迭代器。
举个例子:
import re #导入模块
regex =r'\d+' #编写正则表达式 ,\d+ 匹配一个以上数字
pattern = re.compile(regex) #编译正则表达式并返回一个pattern对象
result = pattern.finditer("abc123abc123")
print(type(result)) #打印返回结果类型
#遍历可迭代的match对象
for i in result:
print(i.group(),'*****',i.span())
执行结果:
5、split 方法
split(string[, maxsplit])
split 方法按照能够匹配的子串将字符串分割后返回列表,其中,maxsplit 用于指定最大分割次数,不指定将全部分割。
举个例子:
import re #导入模块
regex =r'[\s\,\;\!\?]+' #编写正则表达式
pattern = re.compile(regex) #编译正则表达式并返回一个pattern对象
string = '你好呀!你是谁?;你好呀! 我是zzq'
result = pattern.split(string)
print(result)
执行结果:
6、sub 方法
sub(repl, string[, count])
sub 方法用于替换,其中,repl 可以是字符串也可以是一个函数:
- 如果 repl 是字符串,则会使用 repl 去替换字符串每一个匹配的子串,并返回替换后的字符串,另外,repl 还可以使用 id 的形式来引用分组,但不能使用编号 0;
- 如果 repl 是函数,这个方法应当只接受一个参数(Match 对象),并返回一个字符串用于替换(返回的字符串中不能再引用分组)。
- count 用于指定最多替换次数,不指定时全部替换
举个例子:
import re #导入模块
regex =r'\d+' #编写正则表达式 匹配数字
pattern = re.compile(regex) #编译正则表达式并返回一个pattern对象
string = 'abx123xyz456'
result = pattern.sub('XXX',string) #使用'XXX'去替换 123 和 456,也就是说替换说有匹配结果成XXX
print(result)
执行结果:
本篇到此结束!