【Python爬虫实战】正则:多字符匹配、开头与结尾定位、分组技术详解
🌈个人主页:https://blog.csdn.net/2401_86688088?type=blog
🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html

目录
前言
一、匹配多个字符
(一)匹配任意多个字符
(二)匹配一个或多个字符
(三)匹配特定数量的字符
(四)匹配字符范围
(五)匹配非数字、非字母等
(六)使用 re.DOTALL 匹配多行
(七)匹配指定开头或结尾的多个字符
(八)匹配字母、数字、空白符
(九)匹配多个字符总结
二、匹配开头和结尾
(一)匹配字符串的开头:^
(二)匹配字符串的结尾:$
(三)同时匹配开头和结尾
(四)匹配多行模式
(五)示例:验证电子邮件
(六)匹配开头和结尾总结
三、匹配分组
(一)基本分组
(二)命名分组
(三)非捕获分组
(四)使用 groups() 提取所有分组
(五)反向引用分组
(六)分组嵌套
(七)忽略大小写和多行分组匹配
(八)匹配分组总结
四、总结
前言
正则表达式是一种灵活且强大的工具,用于匹配和操作文本。它广泛应用于编程、文本处理、数据清理和验证等领域。在 Python 中,通过内置的 re 模块,开发者可以轻松使用正则表达式来解决复杂的文本匹配问题。本篇文章详细介绍了正则表达式中的多字符匹配、开头和结尾匹配、分组匹配等重要概念及其应用。通过这些示例与技巧,读者将能够掌握如何在 Python 中运用正则表达式处理多种场景下的文本操作需求。
一、匹配多个字符
在正则表达式中,匹配多个字符的方式取决于你要匹配的字符类型和数量。正则表达式通过量词和字符集的组合,能够灵活地匹配任意长度的字符串。以下是一些常见的正则匹配多个字符的方式:
(一)匹配任意多个字符
使用 .* 匹配任意多个字符(包括0个),其中 . 表示任意单个字符,* 表示前面的字符出现0次或多次。
示例:
import re
text = "hello world"
result = re.findall(r'.*', text)
print(result) # 输出: ['hello world', '']
(二)匹配一个或多个字符
使用 + 匹配前面的字符一次或多次,保证至少匹配一个字符。
示例:
import re
text = "abc123"
result = re.findall(r'\d+', text)
print(result) # 输出: ['123']
(三)匹配特定数量的字符
-
使用
{n}来精确匹配前面的字符n次。 -
使用
{n,m}来匹配前面的字符至少n次,至多m次。
示例:
import re
text = "12345"
# 匹配恰好5个数字
result = re.findall(r'\d{5}', text)
print(result) # 输出: ['12345']
(四)匹配字符范围
使用字符集 [] 匹配多个特定字符,或者使用字符范围(如 [a-z])来匹配多个连续字符。
示例:
import re
text = "abcdef123"
result = re.findall(r'[a-f]+', text) # 匹配a-f范围内的多个字符
print(result) # 输出: ['abcdef']
(五)匹配非数字、非字母等
使用反向匹配 [^] 来匹配多个不属于某类的字符。例如,[^0-9]+ 匹配非数字的字符序列。
示例:
import re
text = "abc123def"
# 匹配非数字的字符序列
result = re.findall(r'[^0-9]+', text)
print(result) # 输出: ['abc', 'def']
(六)使用 re.DOTALL 匹配多行
使用 re.DOTALL 标志符,使 . 能够匹配包括换行符在内的所有字符,通常用于匹配跨多行的文本。
示例:
import re
text = "line1\nline2"
# 不使用 DOTALL,无法匹配换行符
result = re.findall(r'.+', text)
print(result) # 输出: ['line1', 'line2']# 使用 DOTALL,可以匹配换行符
result = re.findall(r'.+', text, re.DOTALL)
print(result) # 输出: ['line1\nline2']
(七)匹配指定开头或结尾的多个字符
使用 ^ 表示匹配字符串的开头,$ 表示匹配字符串的结尾。例如 ^abc 匹配以 abc 开头的字符串,abc$ 匹配以 abc 结尾的字符串。
示例:
import re
text = "abc123abc"
# 匹配以 abc 开头的字符串
result = re.findall(r'^abc', text)
print(result) # 输出: ['abc']# 匹配以 abc 结尾的字符串
result = re.findall(r'abc$', text)
print(result) # 输出: ['abc']
(八)匹配字母、数字、空白符
-
使用
\w+匹配多个字母、数字或下划线字符。 -
使用
\d+匹配多个数字。 -
使用
\s+匹配多个空白字符(如空格、制表符、换行符)。
示例:
import re
text = "abc 123"
# 匹配多个字母或数字
result = re.findall(r'\w+', text)
print(result) # 输出: ['abc', '123']# 匹配多个空格
result = re.findall(r'\s+', text)
print(result) # 输出: [' ']
(九)匹配多个字符总结
正则表达式可以通过使用量词、字符集和特殊符号来匹配多个字符。无论是匹配任意字符、特定字符、字符集,还是根据字符出现次数来匹配,正则表达式都可以提供灵活和强大的解决方案。熟练掌握这些技巧后,你可以有效处理多种文本处理需求。
二、匹配开头和结尾
在正则表达式中,使用 ^ 和 $ 分别可以匹配字符串的开头和结尾。它们的具体用法如下:
(一)匹配字符串的开头:^
^ 用于匹配字符串的开头。只有当字符串以指定的模式开头时,才会匹配成功。
示例: 假设我们想匹配以 "hello" 开头的字符串:
import re
text = "hello world"
result = re.findall(r'^hello', text)
print(result) # 输出: ['hello']
如果字符串不是以 "hello" 开头,则匹配会失败:
text = "world hello"
result = re.findall(r'^hello', text)
print(result) # 输出: []
(二)匹配字符串的结尾:$
$ 用于匹配字符串的结尾。只有当字符串以指定的模式结尾时,才会匹配成功。
示例: 假设我们想匹配以 "world" 结尾的字符串:
import re
text = "hello world"
result = re.findall(r'world$', text)
print(result) # 输出: ['world']
如果字符串不是以 "world" 结尾,则匹配会失败:
text = "world hello"
result = re.findall(r'world$', text)
print(result) # 输出: []
(三)同时匹配开头和结尾
可以结合 ^ 和 $ 同时使用,来匹配整个字符串的模式。例如,匹配完整的字符串 "hello world":
import re
text = "hello world"
result = re.findall(r'^hello world$', text)
print(result) # 输出: ['hello world']
示例:
import re
text = "hello world"
result = re.findall(r'^hello world$', text)
print(result) # 输出: ['hello world']
这个模式要求整个字符串必须是 "hello world",否则匹配不会成功:
text = "hello world!"
result = re.findall(r'^hello world$', text)
print(result) # 输出: []
(四)匹配多行模式
默认情况下,^ 和 $ 只会匹配整个字符串的开头和结尾。如果要在多行字符串中分别匹配每一行的开头和结尾,可以使用 re.MULTILINE 标志。
示例:
import re
text = """hello world
goodbye world"""
# 匹配每行的开头为 'hello' 或 'goodbye'
result = re.findall(r'^(hello|goodbye)', text, re.MULTILINE)
print(result) # 输出: ['hello', 'goodbye']
在这种情况下,^ 和 $ 会作用于每一行的起始和结束位置,而不仅仅是整个字符串的起始和结束。
(五)示例:验证电子邮件
假设我们需要验证电子邮件地址的格式,要求它以字母或数字开头,包含 @,并以域名结尾。可以结合 ^ 和 $ 来确保整个字符串符合电子邮件格式:
import re
email = "user@example.com"
pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
result = re.match(pattern, email)
if result:print("有效的电子邮件地址")
else:print("无效的电子邮件地址")
(六)匹配开头和结尾总结
匹配开头和结尾总结起来有以下几点:
-
^用于匹配字符串的开头。 -
$用于匹配字符串的结尾。 -
re.MULTILINE标志可以使^和$作用于每一行的开头和结尾,而不仅限于整个字符串。 -
结合
^和$可以确保整个字符串完全匹配特定的模式。
三、匹配分组
正则表达式中的分组功能可以通过使用圆括号 () 来实现,分组的作用是将表达式的某一部分进行分组匹配,并可以通过分组提取具体的匹配结果。分组是正则表达式非常强大的功能,允许我们对匹配的结果进行更灵活的操作。
(一)基本分组
使用圆括号 () 来将正则表达式中的某个部分进行分组。分组的内容会被单独提取出来,分组后可以通过 Match 对象的 .group() 或 .groups() 方法来获取匹配的分组内容。
示例:匹配并提取姓名和年龄
import re
text = "姓名: 张三, 年龄: 25"
# 使用分组来分别匹配姓名和年龄
pattern = r"姓名:\s(\w+),\s年龄:\s(\d+)"
result = re.search(pattern, text)if result:print(result.group(1)) # 输出: 张三print(result.group(2)) # 输出: 25
在上面的例子中,正则表达式中的两个括号分别对名字和年龄进行了分组,因此可以通过 group(1) 和 group(2) 来获取第一个和第二个匹配的分组。
(二)命名分组
命名分组允许你为分组指定一个名字,这样你可以通过分组名称来访问匹配结果,而不是使用数字索引。命名分组的语法是 (?P<name>...),其中 name 是分组的名字。
示例:使用命名分组提取姓名和年龄
import re
text = "姓名: 李四, 年龄: 30"
# 使用命名分组为姓名和年龄命名
pattern = r"姓名:\s(?P<name>\w+),\s年龄:\s(?P<age>\d+)"
result = re.search(pattern, text)if result:print(result.group("name")) # 输出: 李四print(result.group("age")) # 输出: 30
在这种方式下,你可以通过分组的名称 name 和 age 来提取匹配的内容,代码更加清晰。
(三)非捕获分组
有时我们只想对表达式进行分组,而不希望捕获这个分组的匹配结果。可以使用 (?:...) 来创建一个非捕获分组。这样该分组参与匹配,但不会出现在匹配的结果中。
示例:使用非捕获分组
import re
text = "apple, banana, cherry"
# 使用非捕获分组来匹配不同的水果
pattern = r"(?:apple|banana|cherry)"
result = re.findall(pattern, text)
print(result) # 输出: ['apple', 'banana', 'cherry']
在这个例子中,(?:...) 只是用来匹配,但不会被作为分组结果提取。
(四)使用 groups() 提取所有分组
使用 groups() 可以一次性提取所有分组的匹配内容,返回的是一个包含所有分组内容的元组。
示例:提取所有分组内容
import re
text = "姓名: 王五, 年龄: 40"
pattern = r"姓名:\s(\w+),\s年龄:\s(\d+)"
result = re.search(pattern, text)if result:print(result.groups()) # 输出: ('王五', '40')
这里 groups() 返回了一个包含所有匹配的元组,分别是姓名和年龄。
(五)反向引用分组
-
正则表达式允许在匹配时引用前面匹配到的分组内容。这通常用于验证某些内容的重复,例如匹配重复的字符或词组。
-
反向引用的语法是
\1,\2等,其中数字表示对应的分组。
示例:匹配重复的单词
import re
text = "hello hello world"
# 使用反向引用匹配重复的单词
pattern = r"(\b\w+\b)\s+\1"
result = re.search(pattern, text)if result:print(result.group()) # 输出: hello hello
在这个例子中,(\b\w+\b) 匹配了一个单词,\1 引用了第一个分组的内容,从而匹配重复的单词。
(六)分组嵌套
分组可以嵌套使用,内层的分组优先级高,嵌套的分组也会有索引。
示例:嵌套分组
import re
text = "I have 2 apples and 3 oranges."
# 匹配数量和水果类型,使用嵌套分组
pattern = r"(\d+) (apples|oranges)"
result = re.findall(pattern, text)
print(result) # 输出: [('2', 'apples'), ('3', 'oranges')]
在这个例子中,外层分组 (\d+) 匹配数量,内层分组 (apples|oranges) 匹配水果类型,最终通过 findall() 返回所有匹配项。
(七)忽略大小写和多行分组匹配
如果想在分组匹配时忽略大小写或处理多行匹配,可以使用 re.IGNORECASE 和 re.MULTILINE 等标志。
示例:忽略大小写的分组匹配
import re
text = "HELLO world"
# 使用 re.IGNORECASE 忽略大小写
pattern = r"(hello) (world)"
result = re.search(pattern, text, re.IGNORECASE)if result:print(result.groups()) # 输出: ('HELLO', 'world')
(八)匹配分组总结
分组在正则表达式中非常强大,既可以捕获匹配结果,也可以通过命名分组来提高代码的可读性。非捕获分组可以避免捕获不必要的信息,而反向引用则能够对重复内容进行验证。掌握分组的这些技巧可以极大增强正则表达式处理复杂文本的能力。
四、总结
正则表达式提供了一种简洁高效的方式来匹配和处理文本。本篇文章通过多个实际示例,展示了如何匹配多个字符、匹配字符串的开头和结尾,以及如何灵活运用分组来提取数据。在掌握了这些基本用法后,读者可以轻松应对各种复杂的文本处理任务。正则表达式虽然语法相对简洁,但功能极其强大。通过熟练运用分组、反向引用、命名分组等高级技巧,开发者可以显著提高代码的灵活性与可读性。
相关文章:
【Python爬虫实战】正则:多字符匹配、开头与结尾定位、分组技术详解
🌈个人主页:https://blog.csdn.net/2401_86688088?typeblog 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、匹配多个字符 (一)匹配任意多个字符 ࿰…...
DOIP协议介绍-1
1.DOIP中的GID和EID是什么? 在DOIP(Diagnostics over IP)中,GID(Group Identification)和EID(Entity Identification)是两个重要的标识符,它们各自承担着不同的角色和功…...
探索Python中的多线程与多进程
在Python编程中,多线程和多进程是两个重要的概念,它们被用来提高程序的执行效率。本文将深入探讨这两个概念,并对比它们在Python中的实现方式。 一、多线程 多线程是一种并发执行的程序设计方法。在Python中,我们可以使用thread…...
paypal php 实现详细攻略
一、准备工作 登录 https://www.paypal.com/ 注册一个主账号(选择个人账号、企业账后都可) 申请完成后登录https://developer.paypal.com/ 在后台右侧菜地点击“Accounts”,可以看到系统自动给分配的两个沙箱环境的账号。类型为Personal是个人…...
深入理解Dubbo原理鱼实现,提升职场竞争力
小熊学Java全能学习面试指南:https://www.javaxiaobear.cn 1、RPC RPC(Remote Procedure Call)远程过程调用,它是一种通过网络从远程计算机程序上请求服务。 大白话理解就是:RPC让你用别人家的东西就像自己家的一样。 RPC两个作用࿱…...
自动化测试与敏捷开发的重要性
敏捷开发与自动化测试是现代软件开发中两个至关重要的实践,它们相互补充,共同促进了软件质量和开发效率的提升。 敏捷开发的重要性 敏捷开发是一种以人为核心、迭代、循序渐进的软件开发方法。它强调以下几个核心价值观和原则: 个体和交互…...
气膜:冰雪产业的创新解决方案—轻空间
随着冰雪运动的普及和发展,如何在不同季节和地区有效开展冰雪项目,成为了行业内的一个重要课题。气膜作为一种新兴的建筑形式,凭借其独特的优势,正在逐渐成为冰雪产业的创新解决方案。 优越的建筑特性 气膜建筑以其轻便、快速搭建…...
期货配资网/分仓多元化/配资系统服务商
提供期货配资服务的网络平台搭建服务。这些平台致力于为投资者提供高效、便捷的期货投资渠道,通过配资的方式放大投资者的资金杠杆,从而增加其盈利机会。期货配资网一般具有以下特点: 专业服务:提供期货交易、投资管理及信息咨询…...
「漏洞复现」百易云资产管理运营系统 ufile.api.php SQL注入漏洞
0x01 免责声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,如有侵权请联系删…...
Vue 3 和 Vue Router 使用 createWebHistory 配置
在 Vue 3 项目中,如果使用 Vue Router 并希望启用 HTML5 History 模式,需要在创建路由器实例时传入 createWebHistory 作为历史模式的配置。此外,还需要确保在生产环境中设置正确的基本路径(base),这样才能…...
Nginx:rewrite指令之flag标志
Nginx 的 rewrite 指令用于根据正则表达式来匹配请求的 URI,并将其重写为新的 URI。rewrite 指令可以包含一个可选的 flag(标志),该标志用于控制重写操作后的行为。 rewrite regex replacement [flag] 一. 常用四种 flag redir…...
C#从零开始学习(如何构建应用)
开始使用 C# 开发使用的软件Visual Studio 2019 文章所有的代码都放在 https://github.com/hikinazimi/head-first-Csharp 创建一个控制台应用 打开Visual Studio 2019 创建项目 选择控制台应用程序 创建后点击运行,就可以在控制台打印Hello World 构建一个游戏(创建WPF项目…...
FCoE简介
数据中心融合网络的发展趋势 如图1所示,传统数据中心组网中,以太网LAN(Local Area Network)用于服务器与服务器、客户端与服务器之间通信,存储区域网络SAN(Storage Area Network)用于服务器与存…...
论文笔记:Template-Based Named Entity Recognition Using BART
论文来源:ACL 2021 Finding 论文链接:https://aclanthology.org/2021.findings-acl.161.pdf 论文代码:GitHub - Nealcly/templateNER: Source code for template-based NER 笔记仅供参考,撰写不易,请勿恶意转载抄袭…...
【Nestjs】从入门到精通(依赖注入)
NestJS 是一个基于 Node.js 的渐进式框架,构建在 Express 或 Fastify 之上,主要用于构建高效、可扩展的服务器端应用程序。它使用 TypeScript 并借鉴了 Angular 的设计理念,采用了依赖注入(IoC, Inversion of Control)…...
C语言函数
1.C语言函数的定义 C源程序是由函数组成的。最简单的程序有一个主函数main(),但实用程序往往由多个函数组成,由主函数调用其他函数,其他函数也可以互相调用。函数是C源程序的基本模块,程序的许多功能是通过对函数模块的调用来实现…...
FLINK SQLTable API 的基本概念及常用API
基本概念 SQL和Table API是Apache Flink提供的两个关系型API,它们被设计用于统一的流和批处理。以下是关于SQL和Table API的基本概念及常用API的详细介绍: 一、基本概念 Table API 定义:Table API是一个为Java、Scala和Python提供的语言集…...
Docker daemon.json配置参数及格式帮助信息
我们知道程序运行,通过修改命令参数或者配置文件配置项,对程序进行修改。Docker也不例外,通过docker.service 增加命令参数或者在/etc/docker/daemon.json中增加配置项均可。 推荐修改daemon.json对docker守护进程进行配置更改(方…...
十月编程语言排行榜~
前言:TIOBE编程语言排行榜通过分析全球开发者的活动、代码搜索和问答社区的流量,提供了编程语言受欢迎度的动态图景。该指数是技术趋势的风向标,揭示了哪些编程语言在技术领域占据主导地位,哪些语言正在快速崛起或逐渐衰退。 ✨✨…...
十三、行为型(策略模式)
策略模式(Strategy Pattern) 概念 策略模式(Strategy Pattern)是一种行为型设计模式,允许定义一系列算法,将每个算法封装在策略类中,并使它们可以互换使用。客户端可以根据需要动态选择不同的策…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...
Pandas 可视化集成:数据科学家的高效绘图指南
为什么选择 Pandas 进行数据可视化? 在数据科学和分析领域,可视化是理解数据、发现模式和传达见解的关键步骤。Python 生态系统提供了多种可视化工具,如 Matplotlib、Seaborn、Plotly 等,但 Pandas 内置的可视化功能因其与数据结…...
C/Python/Go示例 | Socket Programing与RPC
Socket Programming介绍 Computer networking这个领域围绕着两台电脑或者同一台电脑内的不同进程之间的数据传输和信息交流,会涉及到许多有意思的话题,诸如怎么确保对方能收到信息,怎么应对数据丢失、被污染或者顺序混乱,怎么提高…...
