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.总结

学会了正则表达式,我们就可以定向查找网页中的某些内容了,快去结合爬虫练练手吧。
目录
相关文章
|
4天前
|
数据采集 存储 数据挖掘
Python数据分析:Pandas库的高效数据处理技巧
【10月更文挑战第27天】在数据分析领域,Python的Pandas库因其强大的数据处理能力而备受青睐。本文介绍了Pandas在数据导入、清洗、转换、聚合、时间序列分析和数据合并等方面的高效技巧,帮助数据分析师快速处理复杂数据集,提高工作效率。
19 0
|
3天前
|
数据采集 JSON 测试技术
Python爬虫神器requests库的使用
在现代编程中,网络请求是必不可少的部分。本文详细介绍 Python 的 requests 库,一个功能强大且易用的 HTTP 请求库。内容涵盖安装、基本功能(如发送 GET 和 POST 请求、设置请求头、处理响应)、高级功能(如会话管理和文件上传)以及实际应用场景。通过本文,你将全面掌握 requests 库的使用方法。🚀🌟
19 7
|
19天前
|
网络协议 数据库连接 Python
python知识点100篇系列(17)-替换requests的python库httpx
【10月更文挑战第4天】Requests 是基于 Python 开发的 HTTP 库,使用简单,功能强大。然而,随着 Python 3.6 的发布,出现了 Requests 的替代品 —— httpx。httpx 继承了 Requests 的所有特性,并增加了对异步请求的支持,支持 HTTP/1.1 和 HTTP/2,能够发送同步和异步请求,适用于 WSGI 和 ASGI 应用。安装使用 httpx 需要 Python 3.6 及以上版本,异步请求则需要 Python 3.8 及以上。httpx 提供了 Client 和 AsyncClient,分别用于优化同步和异步请求的性能。
python知识点100篇系列(17)-替换requests的python库httpx
|
4天前
|
机器学习/深度学习 数据采集 算法
Python机器学习:Scikit-learn库的高效使用技巧
【10月更文挑战第28天】Scikit-learn 是 Python 中最受欢迎的机器学习库之一,以其简洁的 API、丰富的算法和良好的文档支持而受到开发者喜爱。本文介绍了 Scikit-learn 的高效使用技巧,包括数据预处理(如使用 Pipeline 和 ColumnTransformer)、模型选择与评估(如交叉验证和 GridSearchCV)以及模型持久化(如使用 joblib)。通过这些技巧,你可以在机器学习项目中事半功倍。
13 3
|
7天前
|
数据采集 数据可视化 数据处理
如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`)
本文介绍了如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`),加载历史数据,计算均线和其他技术指标,实现交易逻辑,记录和可视化交易结果。示例代码展示了如何根据均线交叉和价格条件进行开仓、止损和止盈操作。实际应用时需注意数据质量、交易成本和风险管理。
25 5
|
5天前
|
存储 数据挖掘 数据处理
Python数据分析:Pandas库的高效数据处理技巧
【10月更文挑战第26天】Python 是数据分析领域的热门语言,Pandas 库以其高效的数据处理功能成为数据科学家的利器。本文介绍 Pandas 在数据读取、筛选、分组、转换和合并等方面的高效技巧,并通过示例代码展示其实际应用。
17 1
|
15天前
|
数据可视化 数据挖掘 Python
Seaborn 库创建吸引人的统计图表
【10月更文挑战第11天】本文介绍了如何使用 Seaborn 库创建多种统计图表,包括散点图、箱线图、直方图、线性回归图、热力图等。通过具体示例和代码,展示了 Seaborn 在数据可视化中的强大功能和灵活性,帮助读者更好地理解和应用这一工具。
30 3
|
1天前
|
调度 开发者 Python
Python中的异步编程:理解asyncio库
在Python的世界里,异步编程是一种高效处理I/O密集型任务的方法。本文将深入探讨Python的asyncio库,它是实现异步编程的核心。我们将从asyncio的基本概念出发,逐步解析事件循环、协程、任务和期货的概念,并通过实例展示如何使用asyncio来编写异步代码。不同于传统的同步编程,异步编程能够让程序在等待I/O操作完成时释放资源去处理其他任务,从而提高程序的整体效率和响应速度。
|
3天前
|
文字识别 自然语言处理 API
Python中的文字识别利器:pytesseract库
`pytesseract` 是一个基于 Google Tesseract-OCR 引擎的 Python 库,能够从图像中提取文字,支持多种语言,易于使用且兼容性强。本文介绍了 `pytesseract` 的安装、基本功能、高级特性和实际应用场景,帮助读者快速掌握 OCR 技术。
22 0
|
20天前
|
Linux Android开发 开发者
【Python】GUI:Kivy库环境安装与示例
这篇文章介绍了 Kivy 库的安装与使用示例。Kivy 是一个开源的 Python 库,支持多平台开发,适用于多点触控应用。文章详细说明了 Kivy 的主要特点、环境安装方法,并提供了两个示例:一个简单的 Hello World 应用和一个 BMI 计算器界面。
30 0