爬虫与Python:(三)基本库的使用——4.re正则使用
正则表达式是一个特殊的字符序列,它能帮助用户便捷地检索一个字符串是否与某种模式匹配。在爬虫中我们经常会使用它来抓取到网页源码或接口返回内容中匹配提取我们想要的数据。
Python自1.5增加了re模块,它提供Perl风格的正则表达式模式。re模块使Python语言拥有全部正则表达式的功能。
re模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串作为它们的第一个参数。本文主要介绍Python中常用的正则表达式处理函数。目录如下:
1. re.match 函数
re.match尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功,那么match()就返回None。re.match的语法格式如下:
re.match(pattern , string , flags=0)
参数说明如下表:
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用于控制正则表达式匹配方式,如是否区分大小写、是否多行匹配等 |
匹配成功re.match返回一个匹配对象,否则返回None。还可以使用group(num)或groups匹配对象函数来获取匹配表达式。
匹配对象方法 | 描述 |
group(num=0) | 匹配整个表达式的字符串,group()可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应的元组 |
group | 返回一个包含所有小组字符串的元组,从1到所含的小组号 |
了解了以上内容,下面来一个示例代码:
1 import re 2 3 print(re.match('www','www.baidu.com').span()) # 在起始位置匹配 4 print(re.match('com','www.baidu.com')) # 不在起始位置匹配
运行后控制台会输出:
(0, 3)
None
获取匹配表达式示例代码如下:
1 import re 2 3 line="Cats are smarter than dogs" 4 matchObj= re.match(r'(.*).are.(.*?).*',line); 5 6 if matchObj: 7 print("matachObj.group()",matchObj.group()) 8 print("matachObj.group(1)",matchObj.group(1)) 9 print("matachObj.group(2)",matchObj.group(2)) 10 else: 11 print("No match!")
运行后控制台会输出:
matachObj.group() Cats are smarter than dogs matachObj.group(1) Cats matachObj.group(2)
2. re.search 函数
re.search用于扫描整个字符串并返回第一个成功的匹配。re.search的语法如下:
re.search(pattern , string ,flagx=0)
re.search有3个参数,作用与re.match一一致。需要注意的是flags参数可写可不写,因为它的底层给了默认值。
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用于控制正则表达式匹配方式,如是否区分大小写、是否多行匹配等 |
示例代码如下:
1 import re 2 3 print(re.search('www','www.baidu.com').span()) # 在起始位置匹配 4 print(re.search('com','www.baidu.com').span()) # 不在起始位置匹配
运行后控制台会输出:
(0, 3)
(10, 13)
可以看到,匹配成功了,它会返回一个元组,该元组包含内容的开始位置和结束位置。
3. re.match 与re.search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,知道找到一个匹配。
示例代码如下:
1 import re 2 3 line="Cats are smarter than dogs" 4 5 6 # match匹配 7 matchObj= re.match(r'dogs',line); 8 if matchObj: 9 print("match-->matchObj.group()",matchObj.group()) 10 else: 11 print("No match!") 12 13 # search匹配 14 matchObj= re.search(r'dogs',line); 15 if matchObj: 16 print("search-->matchObj.group():",matchObj.group()) 17 else: 18 print("No match!")
运行后控制台会输出:
No match!
search-->matchObj.group(): dogs
4. 检索和替换
当需要替换某段文字的某些内容时,例如:“等忙完这一阵,就可以接着忙下一阵了”。这里想把“忙”字替换成“过”该如何解决?re中提供了模块re.sub可以用于替换字符串中的匹配项。语法格式如下:
re.sub(pattern,repl,count=0 , flags=0)
re.sub的几个参数说明如下:
参数 | 描述 |
pattern | 正则中的模式字符串。 |
repl | 替换的字符串,也可我一个函数。 |
string | 要被查找或替换的原始字符串 |
count | 模式匹配后替换的最大次数,默认wi0 ,表示替换所有的匹配 |
示例代码如下:
1 import re 2 3 st = "等忙完这一阵,就可以接着忙下一阵了。" 4 5 # 替换其中的“忙”字 6 new_str = re.sub(r'忙',"过",st) 7 print("替换后的句子:",new_str) # 替换后的句子: 等过完这一阵,就可以接着过下一阵了。
5. re.complile函数
re.complile用于编译表达式,生成一个正则表达式{patter}对象,供match()和search()函数使用,re.complile函数语法格式如下:
re.compile(pattern,flags)
参数说明如下:
- patterern : 一个字符串形式的正则表达式
- flags: 可选参数,表示匹配模式,如忽略大小写、多行模式等。具体参数如下:
值 | 描述 |
rel | 忽略大小写 |
re.I | 表示特殊字符集\w、\W、\b、\B、\s、\S 依赖当前环境 |
re.M | 多行模式 |
re.S | 即为 . ,并且包括换行符在内任意字符(.不包括换行符)。 |
re.U | 表示特殊字符集 |
re.X | 为了增加可读性,忽略空格和#后面的注释 |
下面我们来看一个示例:
1 import re 2 3 pattern = re.compile(r'\d+') # 用于匹配至少一个数字 4 m1 = pattern.match('one12wothree34hour') # 查找头部,没有匹配 5 m2 = pattern.match('one12wothree34hour',2,10) # 从'e'的位置开始匹配,没有匹配 6 m3 = pattern.match('one12wothree34hour',3,10) # 从1的位置开始匹配,正好匹配 7 8 print(m1) 9 print(m2) 10 print(m3) 11 print(m3.group(0)) 12 print(m3.start(0)) 13 print(m3.end(0)) 14 print(m3.span(0))
运行结果如下图:
在来一个示例:
1 import re 2 3 pattern = re.compile(r'([a-z]+)([a-z]+)',re.I) # re.l表示忽略大小写 4 m = pattern.match('Hello World Wide Web') 5 6 print(m) 7 print(m.group(0)) # 返回匹配成功的子串 8 print(m.span(0)) # 返回匹配成功的整个子串的索引 9 print(m.group(1)) # 返回第一个分组匹配成功的子串 10 print(m.span(1)) # 返回第一个分组匹配成功的子串的索引 11 print(m.group(2)) # 返回第二个分组匹配成功的子串 12 print(m.span(2)) # 返回第二个分组匹配成功的子串的索引 13 print(m.groups()) # 等价于(m.group(1),m.group(2),……) 14 print(m.group(3)) # 不存在第三个分组
运行结果如下图:
6.findall 函数
finnal用于在字符串中找到正则表达式所匹配的子串,并返回一个列表,如果没有找到匹配的,则返回空列表。findall的语法如下:
findall(string,pos[,endpos])
参数说明如下:
- string : 待匹配的字符串。
- pos 可选参数,指定字符串的起始位置,默认为0。
- endpos : 可选参数,指定字符串的结束位置,默认为字符串长度
接下来,我们来查找字符串中的所有数字。
1 import re 2 3 pattern = re.compile(r'\d+') # 查找数字 4 result1 = pattern.findall('runoob 123 google 456') 5 result2 = pattern.findall('run88oob123google456',0 ,10) 6 7 print(result1) 8 print(result2)
运行结果如下:
['123', '456'] ['88', '12']