Python 网络爬虫笔记6 – 正则表达式
Python 网络爬虫系列笔记是笔者在学习嵩天老师的《Python网络爬虫与信息提取》课程及笔者实践网络爬虫的笔记。
课程链接:Python网络爬虫与信息提取
参考文档:
Requests 官方文档(英文)
Requests 官方文档(中文)
Beautiful Soup 官方文档
re 官方文档
Scrapy 官方文档(英文)
Scrapy 官方文档(中文)
一、正则表达式
1、介绍
正则表达式,又称规则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
2、基础语法
操作符 | 说明 | 实例 |
---|---|---|
. | 表示任何单个字符 | |
[ ] | 字符集,对单个字符给出取值范围 | [abc]表示a、b、c,[a‐z]表示a到z单个字符 |
[ ^ ] | 非字符集,对单个字符给出排除范围 | [ ^abc]表示非a或b或c的单个字符 |
* | 前一个字符0次或无限次扩展 | abc* 表示ab、abc、abcc、abccc等 |
+ | 前一个字符1次或无限次扩展 | abc+ 表示abc、abcc、abccc等 |
? | 前一个字符0次或1次扩展 | abc? 表示ab、abc |
| | 左右表达式任意一个 | abc|def 表示abc、def |
{m} | 扩展前一个字符m次 | ab{2}c表示abbc |
{m,n} | 扩展前一个字符m至n次(含n) | ab{1,2}c表示abc、abbc |
^ | 匹配字符串开头 | ^abc表示abc且在一个字符串的开头 |
$ | 匹配字符串结尾 | abc$表示abc且在一个字符串的结尾 |
( ) | 分组标记,内部只能使用| 操作符 | (abc)表示abc,(abc|def)表示abc、def |
\d | 数字,等价于[0‐9] | |
\D | 匹配一个非数字字符,等价于[ ^0-9] | |
\w | 单词字符,等价于[A‐Za‐z0‐9_] | |
\W | 匹配任何非单词字符,等价于“[ ^A-Za-z0-9_]”。 | |
\f | 匹配一个换页符,等价于\x0c和\cL。 | |
\n | 匹配一个换行符,等价于\x0a和\cJ。 | |
\r | 匹配一个回车符,等价于\x0d和\cM。 | |
\s | 匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 | |
\S | 匹配任何可见字符,等价于[^ \f\n\r\t\v]。 | |
\t | 匹配一个制表符,等价于\x09和\cI。 | |
\v | 匹配一个垂直制表符,等价于\x0b和\cK。 |
贪婪匹配与最小匹配: 默认为贪婪匹配,加上?就可以实现最小匹配。
操作符 | 说明 |
---|---|
*? | 前一个字符0次或无限次扩展,最小匹配 |
+? | 前一个字符1次或无限次扩展,最小匹配 |
?? | 前一个字符0次或1次扩展,最小匹配 |
{m,n}? | 扩展前一个字符m至n次(含n),最小匹配 |
3、经典正则化表达式实例
# 由26个字母组成的字符串
^[A‐Za‐z]+$
# 由26个字母和数字组成的字符串
^[A‐Za‐z0‐9]+$
# 整数形式的字符串
^‐?\d+$
# 正整数形式的字符串
^[0‐9]*[1‐9][0‐9]*$
# 中国境内邮政编码,6位
[1‐9]\d{5}
# 匹配中文字符
[\u4e00‐\u9fa5]
# 国内电话号码,010‐68913536
\d{3}‐\d{8}|\d{4}‐\d{7}
# IP地址字符串, 0‐99: [1‐9]?\d 100‐199: 1\d{2} 200‐249: 2[0‐4]\d 250‐255: 25[0‐5]
(([1‐9]?\d|1\d{2}|2[0‐4]\d|25[0‐5]).){3}([1‐9]?\d|1\d{2}|2[0‐4]\d|25[0‐5])
二、re 库
1、基础
导入:
# python自带re库,不需要安装
import re
raw string 类型:
- raw string类型:原生字符串类型,不需要转义字符来表示特殊字符
- re库采用raw string类型表示正则表达式
# 通用格式,在字符串前加 r
r'regex'
# 示例,不会对\进行转义
r'[1‐9]\d{5}'
r'\d{3}‐\d{8}|\d{4}‐\d{7}'
2、re 库函数
函数表: 函数在内部会对正则表达式进行编译再匹配
函数 | 说明 |
---|---|
re.search(pattern, string, flags=0) | 在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象 |
re.match(pattern, string, flags=0) | 从一个字符串的开始位置起匹配正则表达式,返回match对象 |
re.findall(pattern, string, flags=0) | 搜索字符串,以列表类型返回全部能匹配的子串 |
re.split(pattern, string, maxsplit=0, flags=0) | 将一个字符串按照正则表达式匹配结果进行分割,返回列表类型 |
re.finditer(pattern, string, flags=0) | 搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象 |
re.sub(pattern, repl, string, count=0, flags=0) | 在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串 |
参数
- pattern:正则表达式的字符串或原生字符串表示
- string:待匹配字符串
- flags:正则表达式使用时的控制标记
- re.I re.IGNORECASE:忽略正则表达式的大小写,[A‐Z]能够匹配小写字符
- re.M re.MULTILINE:正则表达式中的^操作符能够将给定字符串的每行当作匹配开始
- re.S re.DOTALL:正则表达式中的.操作符能够匹配所有字符,默认匹配除换行外的所有字符
- maxsplit:最大分割数,剩余部分作为最后一个元素输出
- repl:替换匹配字符串的字符串
- count:匹配的最大替换次数
返回: Match对象
属性 | 说明 |
---|---|
.string | 待匹配的文本 |
.re | 匹配时使用的patter对象(正则表达式) |
.pos | 正则表达式搜索文本的开始位置 |
.endpos | 正则表达式搜索文本的结束位置 |
.group(0) | 获得匹配后的字符串 |
.start() | 匹配字符串在原始字符串的开始位置 |
.end() | 匹配字符串在原始字符串的结束位置 |
.span() | 返回(.start(), .end()) |
示例:
import re
def re_func():
"""
re 库函数使用
"""
string = 'HIT123456 SZ666666'
# search函数
match1 = re.search(r'[1-9]\d{5}', string)
if match1:
# Match对象的属性和方法
print('-'*20)
print(match1.group(0))
print(match1.string)
print(match1.re)
print(match1.pos)
print(match1.endpos)
print(match1.start())
print(match1.end())
print(match1.span())
print('-'*20)
# match 函数
match2 = re.match(r'[1-9]\d{5}', string)
if match2:
print(match2.group(0))
# findall函数
ls1 = re.findall(r'[1-9]\d{5}', string)
print(ls1)
# split函数
ls2 = re.split(r'[1-9]\d{5}', string, maxsplit=1)
print(ls2)
# finditer函数
for m in re.finditer(r'[1-9]\d{5}', string):
if m:
print(m.group(0))
# sub函数
res = re.sub(r'[1-9]\d{5}', 'number', string)
print(res)
if __name__ == '__main__':
print('running regex')
re_func()
3、re.compile()
- 显式编译正则表达式,再匹配
- 可以使用re库中的6种匹配函数
# 使用格式
正则表达式编译后的对象.函数名()
# 示例
pat = re.compile(r'[1-9]\d{5}')
print(pat.search(string).group(0))