Python 正则匹配:re库的使用

简介: 正则表达式是一种描绘字符串的匹配模式,可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。学会了正则表达式,我们就可以定向查找网页中的某些内容了,快去结合爬虫练练手吧。
✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。
🍎个人主页: 小嗷犬的博客
🍊个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。
🥭本文内容:Python 正则匹配:re库的使用

1.引入

正则表达式是一种描绘字符串的匹配模式,可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

比如我们可以使用以下正则表达式来匹配一个网址:

[a-zA-Z]+://[^\s]*
其中 a-z表示匹配任意的小写字母, A-Z表示匹配任意的大写字母, ^\s表示匹配任意的非空白字符, *表示匹配前面的任意多个字符。

本文将介绍正则表达式的基本概念,以及如何使用 Python 的re库进行正则匹配。


2.常用匹配规则

除了我们上一节说到的几个匹配规则之外, 正则表达式还提供了很多的匹配规则,下表列出了常用的一些匹配规则:
模式 描述
\w 匹配字母、数字及下划线
\W 匹配不是宇母、数字及下划线的字符
\s 匹配任意空白字符,等价于[\t\n\r\f]
\S 匹配任意非空字符
\d 匹配任意数字,等价于[0-9]
\D 匹配任意非数字的字符
\A 匹配字符串开头
\Z 匹配字符串结尾。加果存在换行,只匹配到换行前的结束字符串
\z 匹配字符串结尾。如果存在换行,同时还会匹配换行符
\G 匹配最后匹配完成的位置
\n 匹配一个换行符
\t 匹配一个制表符
^ 匹配一行字符串的开头
$ 匹配一行字符串的结尾
. 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,可以匹配包括换行符的任意字符
[...] 用来表示一组字符,单独列出
[^...] 匹配不在[]中的字符
* 匹配0个或多个表达式
+ 匹配1个或多个表达式
? 匹配0个或1个前面的正则表达式定义的片段,非贪婪方式
{n} 精确匹配 n 个前面的表达式
{n, m} 匹配 nm 次由前面正则表达式定义的片段,贪婪方式
a|b 匹配 ab
() 匹配括号内的表达式,也表示一个组

3.re库

re库是 Python 自带的标准库,无需额外安装,使用前需要导入:
import re

3.1 match

我们开始介绍 re中的第一个常用的匹配方法—— match,向它传入要匹配的字符串以及正则表达式,可以检测这个正则表达式是否和字符串相匹配。

match方法会尝试从字符串的起始位置开始匹配正则表达式,如果匹配,就会返回匹配成功的结果,否则返回None

语法格式:

re.match(pattern, string, flags=0)
参数说明:
参数 描述
pattern 正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式
代码实例:
import re

content = "Hello 666 World"
print(len(content))
result = re.match("^Hello\s\d\d\d\sWorld$", content)
print(result)
print(result.group())
print(result.span())

# 输出:
# 15
# <re.Match object; span=(0, 15), match='Hello 666 World'>
# Hello 666 World
# (0, 15)

3.1.1 匹配目标

其中, group方法可以输出匹配到的内容, span方法可以输出匹配的范围。

同时,我们可以通过给group传入索引来获取指定分组的结果,如:

import re

content = "Hello 369 World"
result = re.match("^Hello\s(\d\d)(\d)\sWorld$", content)
print(result.group())
print(result.group(1))
print(result.group(2))

# 输出:
# Hello 369 World
# 36
# 9
这里我们使用了括号 ()将想要提取的子字符串标记出来, group中传入的索引便是第几个括号 ()的位置,用例中的 group(1)便匹配的是 36,而 group(2)匹配的是 9

3.1.2 通用匹配

上面的我们写的正则表达式比较复杂,出现空白字符就用 \s匹配,出现数字就用 \d匹配,这样的写法十分呆板。

其实我们完全没有必要这么复杂,正则表达式为我们提供了万能匹配方式,我们可以使用.*来匹配除换行符以外的任意字符,有了它我们就不用挨个字符进行匹配了。

之前的例子可以改写成:

import re

content = "Hello 666 World"
print(len(content))
result = re.match("^Hello.*World$", content)
print(result)
print(result.group())
print(result.span())

# 输出:
# 15
# <re.Match object; span=(0, 15), match='Hello 666 World'>
# Hello 666 World
# (0, 15)

3.1.3 贪婪方式与非贪婪方式

使用通用匹配 .*时,匹配到的内容可能不是我们想要的。如:
import re

content = "Hello 123456789 World"
result = re.match("^He.*(\d+).*World$", content)
print(result.group())
print(result.group(1))

# 输出:
# Hello 123456789 World
# 9
这里我们想获取目标字符串中间的数字,所以我们使用了 (\d+)匹配中间,用 .*来匹配两边杂乱的字符,但最终 group(1)中输出的是 9这一个数字,与我们想要的结果不同。

这里涉及到贪婪方式和非贪婪方式的问题。

在贪婪方式中,.*会匹配尽可能多的字符,而.*后面是\d+,也就是至少匹配一个数字,所以前面的.*会尽可能的匹配更多的字符,最后就只给\d+留下了9这一个字符。

这样会给我们带来一定的不便,我们可以用非贪婪方式来改写,使其能够获取到我们想要的结果:

import re

content = "Hello 123456789 World"
result = re.match("^He.*?(\d+).*World$", content)
print(result.group())
print(result.group(1))

# 输出:
# Hello 123456789 World
# 123456789
.*的后面加上 ?可以用非贪婪模式,这样它就会匹配尽可能少的字符。

3.1.4 修饰符

我们之前提到了 match的第三个参数 flags,这一节我们来讨论一下这个参数的可选项。

下表包含了可选的修饰符:

修饰符 描述
re.I 使匹配对大小写不敏感
re.L 实现本地化识别(locale-aware)匹配
re.M 多行匹配,影响^$
re.S 使匹配内容包括换行符在内的所有字符
re.U 根据 Unicode 字符集解析字符。影响\w\W\b\B
re.X 忽略正则表达式中的空白和注释
在网页匹配中较为常用的有 re.Sre.I

3.1.5 转义匹配

正则表达式中定义了很多的匹配规则,如用 .匹配除换行符以外的任意字符,如果我们就想让 .来匹配 .这个字符怎么办呢?

我们可以在用作正则表达式匹配的字符前面加上\来转义,使之匹配它原本表示的字符。


3.2 search

上一节我们提到, match是从字符串起始位置开始匹配的,这意味着一旦字符串开头不匹配,我们就无法匹配到任何子字符串。

如:

import re

content = "XiaoAoQuan Hello 123456789 World"
result = re.match("He.*?(\d+).*ld", content)
print(result)

# 输出:
# None
使用 match方法进行匹配时需要考虑字符串的开头内容,使用并不便利。它更适合 判断目标字符串是否符合正则表达式规则

这里就有另外一个方法——search,它会依次以每个字符开头扫描字符串,找到并返回第一个符合条件的结果,如果没找到则返回None

语法格式:

re.search(pattern, string, flags=0)
参数说明:
参数 描述
pattern 正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式
代码实例:
import re

content = "XiaoAoQuan Hello 123456789 World XiaoAoQuan Hello 123456789 "
result = re.search("He.*?(\d+).*World", content)
print(result)
print(result.group(1))

# 输出:
# <re.Match object; span=(11, 32), match='Hello 123456789 World'>
# 123456789

3.3 findall

findall方法和 search方法类似,但它会返回所有与正则表达式匹配的子字符串。
语法格式:
re.findall(pattern, string, flags=0)
参数说明:
参数 描述
pattern 正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式
代码实例:
import re

content = "XiaoAoQuan Hello 123456789 World\nXiaoAoQuan Hello 987654321 World"
result = re.findall("X.*?(\d+).*d", content)
print(result)

# 输出:
# ['123456789', '987654321']

3.4 sub

sub方法类似于字符串中的 replace方法,它可以将替换字符串中符合正则表达式匹配条件的子字符串全部替换为指定字符串。

语法格式:

re.sub(pattern, repl, string, count=0, flags=0)
参数说明:
参数 描述
pattern 正则表达式
repl 替换的目标字符串
string 原字符串
count 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配
代码实例:
import re

content = "XiaoAoQuan Hello 123456789 World\nXiaoAoQuan Hello 987654321 Python"
result = re.sub("\d+", "", content)
print(result)

# 输出:
# XiaoAoQuan Hello  World
# XiaoAoQuan Hello  Python

3.5 compile

compile方法可以将正则表达式字符串编译为正则表达式对象,便于在后续的匹配中反复使用。

语法格式:

re.compile(pattern[, flags])
参数说明:
参数 描述
pattern 正则表达式
flags 标志位,用于控制正则表达式的匹配方式
代码实例:
import re

content = "XiaoAoQuan Hello 123456789 World\nXiaoAoQuan Hello 987654321 World"
pattern = re.compile('X.*?(\d+).*d')
result = pattern.findall(content)
print(result)

# 输出:
# ['123456789', '987654321']

4.总结

学会了正则表达式,我们就可以定向查找网页中的某些内容了,快去结合爬虫练练手吧。
目录
相关文章
|
1天前
|
数据可视化 数据挖掘 API
使用Python进行数据可视化:探索Matplotlib和Seaborn库
【9月更文挑战第19天】在数据科学领域,将复杂的数据集转换成直观、易懂的图形是一项基本而关键的技能。本文旨在通过Python编程语言介绍两个强大的数据可视化库——Matplotlib和Seaborn,以及它们如何帮助数据分析师和研究人员揭示数据背后的故事。我们将从基础概念讲起,逐步深入到高级技巧,确保无论读者的背景如何,都能获得必要的知识和启发,以在自己的项目中实现有效的数据可视化。
|
1天前
|
机器学习/深度学习 JSON API
HTTP协议实战演练场:Python requests库助你成为网络数据抓取大师
在数据驱动的时代,网络数据抓取对于数据分析、机器学习等至关重要。HTTP协议作为互联网通信的基石,其重要性不言而喻。Python的`requests`库凭借简洁的API和强大的功能,成为网络数据抓取的利器。本文将通过实战演练展示如何使用`requests`库进行数据抓取,包括发送GET/POST请求、处理JSON响应及添加自定义请求头等。首先,请确保已安装`requests`库,可通过`pip install requests`进行安装。接下来,我们将逐一介绍如何利用`requests`库探索网络世界,助你成为数据抓取大师。在实践过程中,务必遵守相关法律法规和网站使用条款,做到技术与道德并重。
7 2
|
4天前
|
SQL 前端开发 数据可视化
Rodeo支持多种Python库
Rodeo支持多种Python库
16 5
|
3天前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
在网络数据的海洋中,网络爬虫遵循HTTP协议,穿梭于互联网各处,收集宝贵信息。本文将从零开始,使用Python的requests库,深入解析HTTP协议,助你构建自己的网络爬虫帝国。首先介绍HTTP协议基础,包括请求与响应结构;然后详细介绍requests库的安装与使用,演示如何发送GET和POST请求并处理响应;最后概述爬虫构建流程及挑战,帮助你逐步掌握核心技术,畅游数据海洋。
18 3
|
8天前
|
数据采集 网络协议 API
HTTP协议大揭秘!Python requests库实战,让网络请求变得简单高效
【9月更文挑战第13天】在数字化时代,互联网成为信息传输的核心平台,HTTP协议作为基石,定义了客户端与服务器间的数据传输规则。直接处理HTTP请求复杂繁琐,但Python的`requests`库提供了一个简洁强大的接口,简化了这一过程。HTTP协议采用请求与响应模式,无状态且结构化设计,使其能灵活处理各种数据交换。
37 8
|
12天前
|
JSON API 开发者
Python网络编程新纪元:urllib与requests库,让你的HTTP请求无所不能
【9月更文挑战第9天】随着互联网的发展,网络编程成为现代软件开发的关键部分。Python凭借简洁、易读及强大的特性,在该领域展现出独特魅力。本文介绍了Python标准库中的`urllib`和第三方库`requests`在处理HTTP请求方面的优势。`urllib`虽API底层但功能全面,适用于深入控制HTTP请求;而`requests`则以简洁的API和人性化设计著称,使HTTP请求变得简单高效。两者互补共存,共同推动Python网络编程进入全新纪元,无论初学者还是资深开发者都能从中受益。
31 7
|
19天前
|
机器学习/深度学习 PyTorch 算法框架/工具
python这些库和框架哪个更好
【9月更文挑战第2天】python这些库和框架哪个更好
32 6
|
19天前
|
机器学习/深度学习 数据采集 算法框架/工具
python有哪些常用的库和框架
【9月更文挑战第2天】python有哪些常用的库和框架
21 6
WK
|
19天前
|
数据采集 XML 安全
常用的Python网络爬虫库有哪些?
Python网络爬虫库种类丰富,各具特色。`requests` 和 `urllib` 简化了 HTTP 请求,`urllib3` 提供了线程安全的连接池,`httplib2` 则具备全面的客户端接口。异步库 `aiohttp` 可大幅提升数据抓取效率。
WK
36 1
|
21天前
|
机器学习/深度学习 存储 算法
NumPy 与 SciPy:Python 科学计算库的比较
【8月更文挑战第30天】
55 1