当前位置: 首页 > article >正文

Python:正则表达式

正则表达式的基础和应用

一、正则表达式核心语法(四大基石)

1. ​元字符(特殊符号)​
  • 定位符
    ^:匹配字符串开始位置
    $:匹配字符串结束位置
    \b:匹配单词边界​(如 \bword\b 匹配独立单词)
  • 字符类
    .:任意单个字符(默认不包括换行符)
    \d:数字(等价 [0-9]
    \w:字母、数字、下划线(等价 [a-zA-Z0-9_]
    \s:空白符(空格、Tab、换行等)
  • 转义符
    \:将特殊字符转为普通字符(如 \. 匹配真正的点号)
2. ​量词(重复次数)​
  • *:0次或多次
  • +:1次或多次
  • ?:0次或1次
  • {n}:精确n次
  • {n,}:至少n次
  • {n,m}:n到m次
3. ​字符集合与逻辑
  • [abc]:匹配a、b、c中的任意一个
  • [a-z]:匹配小写字母a到z
  • [^abc]:否定集合(匹配不在abc中的字符)
  • |:逻辑或(如 cat|dog 匹配"cat"或"dog")
4. ​分组与引用
  • ( ):捕获分组(可通过 \1 或 $1 反向引用)
  • (?: ):非捕获分组(仅用于逻辑分组)
  • (?P<name>):命名分组(Python中可通过名称引用)

二、正则引擎工作原理(NFA vs DFA)

1. ​NFA引擎(主流实现)​
  • 特点:支持回溯、捕获组、零宽断言等高级功能,但存在性能风险
  • 匹配流程
    1. 从起始位置尝试匹配
    2. 记录所有可能的分支(回溯点)
    3. 失败时退回最近回溯点继续尝试
    4. 直到匹配成功或完全失败
2. ​DFA引擎
  • 特点:无回溯,线性时间复杂度,但功能受限(不支持分组引用)
  • 流程:一次性扫描文本,无状态回退

三、关键应用场景与解决方案

1. ​数据验证(精准匹配)​
  • 邮箱验证

    ^[\w\.-]+@([\w-]+\.)+[\w-]{2,4}$  
    • ^ 和 $ 确保整行匹配
    • [\w\.-]+ 允许用户名包含字母、数字、点、减号
    • ([\w-]+\.)+ 匹配多级域名(如 "mail." 或 "google.com.")
    • [\w-]{2,4} 匹配顶级域名(如 com、org)
  • 强密码规则

    ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$  
    • (?=.*\d):正向预查确保包含数字
    • (?=.*[a-z]):必须有小写字母
    • (?=.*[A-Z]):必须有大写字母
    • .{8,}:总长度至少8位
2. ​数据提取(捕获关键信息)​
  • 从URL提取域名和路径

    ^https?://([^/?#]+)([^?#]*)  
    • 分组1 ([^/?#]+) 捕获域名(如 www.example.com
    • 分组2 ([^?#]*) 捕获路径(如 /path/to/page
  • 日志时间戳提取

    \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}
    • 精确匹配 YYYY-MM-DD HH:MM:SS 格式
3. ​文本清洗与替换
  • 删除HTML标签

    <[^>]+>  
    • 匹配所有以 < 开头、> 结尾的内容
    • 使用 re.sub(r'<[^>]+>', '', html) 替换为空
  • 格式化电话号码
    输入:1234567890 → 输出:(123) 456-7890

    re.sub(r'(\d{3})(\d{3})(\d{4})', r'(\1) \2-\3', phone)

四、性能优化与避坑指南

1. ​避免灾难性回溯
  • 危险模式(a+)+ 或 .*.*(嵌套量词导致指数级复杂度)
  • 优化方法
    • 用具体字符代替 .*(如 \d+ 代替 .*
    • 使用原子分组 (?>...)(部分引擎支持)
    • 添加锚点限制范围(如 ^...$
2. ​贪婪与非贪婪选择
  • 贪婪模式​(默认):.* 匹配尽可能多内容
    <div>.*</div> → 可能跨多个标签错误匹配
  • 非贪婪模式.*? 匹配最短结果
    <div>.*?</div> → 精确匹配单个标签内容
3. ​预编译与复用
# 预编译提升性能(适用于频繁调用场景)
pattern = re.compile(r'\d{3}-\d{4}')
pattern.findall('Tel: 123-4567')

五、进阶技巧

1. ​零宽断言(Lookaround)​
  • (?=...):正向先行断言(右侧必须满足条件)
    \d+(?=px) → 匹配 "100px" 中的 "100"
  • (?<=...):正向后行断言(左侧必须满足条件)
    (?<=\$)\d+ → 匹配 "$200" 中的 "200"
2. ​条件匹配
(?(id)yes|no) → 根据分组是否存在选择分支
  • 示例:匹配带区号的电话号码
    ($)? \d{3} (?(1)$|) → 匹配 "(123)" 或 "123"

六、好用的工具

  1. 调试工具
    • RegExr:实时高亮匹配结果,显示分组与回溯
    • Regex101:支持多语言引擎,提供错误解释
  2. 可视化工具
    Regexper:图形化展示正则逻辑

七、总结

正则表达式的核心在于 ​模式定义 与 ​引擎匹配机制 的结合。掌握以下要点即可应对90%的场景:

  1. 精准定位:用 ^$\b 约束边界
  2. 明确范围:用字符集合 [...] 和量词 {n,m} 减少模糊匹配
  3. 合理分组:通过 ( ) 提取关键数据
  4. 性能优先:避免嵌套量词,优先使用具体字符

以下是Python中正则表达式的用法


一、环境准备

1. 导入re模块

import re  # Python内置正则库

2. 原始字符串(Raw String)

正则表达式推荐使用原始字符串(前缀 r),避免Python字符串转义冲突:

pattern = r'\d+'  # 正确:匹配数字
pattern = '\\d+'   # 错误:需双重转义,可读性差

二、四大核心方法

1. re.match() - ​从开头匹配

  • 只匹配字符串开头,成功返回Match对象,否则返回None

text = "123abc"
result = re.match(r'\d+', text)
if result:print("匹配成功:", result.group())  # 输出: 123

2. re.search() - ​全局搜索

  • 扫描整个字符串,找到第一个匹配项

text = "abc456def"
result = re.search(r'\d+', text)
print(result.group())  # 输出: 456

3. re.findall() - ​查找所有匹配

  • 返回所有匹配结果的列表​(无分组时返回字符串列表)

text = "1a2b3c"
numbers = re.findall(r'\d', text)
print(numbers)  # 输出: ['1', '2', '3']

4. re.sub() - ​替换匹配内容

  • 将匹配内容替换为指定字符串

text = "2023-01-01"
new_text = re.sub(r'-', '/', text)
print(new_text)  # 输出: 2023/01/01

三、分组与捕获

1. 基本分组 ( )

  • 用括号分组,通过group(index)提取

text = "John:30"
pattern = r'(\w+):(\d+)'
match = re.search(pattern, text)
print(match.group(1))  # John
print(match.group(2))  # 30

2. 非捕获分组 (?: )

  • 分组但不捕获,节省内存

text = "apple orange"
pattern = r'(?:a|an|the) (\w+)'  # 匹配冠词后的单词但不捕获冠词
match = re.search(pattern, text)
print(match.group(1))  # apple

3. 命名分组 (?P<name>)

  • 为分组命名,提升可读性

text = "Date: 2023-08-15"
pattern = r'Date: (?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
match = re.search(pattern, text)
print(match.group('year'))   # 2023
print(match.groupdict())     # {'year': '2023', 'month': '08', 'day': '15'}

四、高级功能

1. 正则标志(Flags)

  • 控制匹配模式的全局行为

text = "Hello\nWorld"
# 多行模式(^和$匹配每行开头结尾)
re.findall(r'^\w+', text, flags=re.MULTILINE)  # 输出: ['Hello', 'World']
# 忽略大小写
re.findall(r'hello', text, flags=re.IGNORECASE)  # 输出: ['Hello']

2. 预编译正则表达式

  • 提升重复使用时的性能

pattern = re.compile(r'\d{3}-\d{4}')  # 编译为RegexObject
result = pattern.findall("Tel: 123-4567")  # ['123-4567']

3. 替换时使用函数

  • 动态生成替换内容

def to_upper(match):return match.group().upper()text = "hello world"
new_text = re.sub(r'\b\w', to_upper, text)
print(new_text)  # 输出: Hello World

五、经典实战案例

1. 验证邮箱格式

def validate_email(email):pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'return re.match(pattern, email) is not Noneprint(validate_email("user@example.com"))  # True
print(validate_email("invalid.email@"))     # False

2. 提取HTML链接

html = '<a href="https://example.com">Link</a>'
pattern = r'href="(https?://[^"]+)"'
match = re.search(pattern, html)
print(match.group(1))  # https://example.com

3. 转换日期格式

date = "2023-08-15"
new_date = re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\2/\3/\1', date)
print(new_date)  # 08/15/2023

六、避坑指南

  1. 贪婪匹配陷阱
    使用 .*? 非贪婪模式避免过度匹配:

    text = "<div>Hello</div><div>World</div>"
    re.findall(r'<div>(.*?)</div>', text)  # ['Hello', 'World']
  2. 特殊字符转义
    匹配 .* 等符号需转义:

    re.findall(r'3\.14', "pi=3.14")  # ['3.14']
  3. 性能优化
    避免在循环中重复编译正则,优先使用预编译。


七、调试工具

  1. 在线测试
    RegExr:实时高亮匹配结果,显示分组信息

  2. 代码调试
    使用 re.DEBUG 标志查看正则解析过程:
    re.compile(r'\d+', re.DEBUG)

相关文章:

Python:正则表达式

正则表达式的基础和应用 一、正则表达式核心语法&#xff08;四大基石&#xff09; 1. ​元字符&#xff08;特殊符号&#xff09;​ ​定位符 ^&#xff1a;匹配字符串开始位置 $&#xff1a;匹配字符串结束位置 \b&#xff1a;匹配单词边界​&#xff08;如 \bword\b 匹配…...

网络通信中的带宽(Bandwidth)概念

在计算机网络中&#xff0c;带宽是指单位时间内可以传输的数据量&#xff0c;通常以比特每秒&#xff08;bps&#xff09;或字节每秒&#xff08;Bps&#xff09;为单位。 1. 理论计算 链路带宽&#xff1a;链路带宽是指网络链路的物理传输能力&#xff0c;通常由网络设备的规…...

基于杀伤链的勒索软件控制框架

40s说清楚勒索软件如何工作 基于杀伤链的勒索软件控制框架开发了4种缓解策略(预防、阻止、检测&响应、重建)&#xff0c;覆盖18个控制域90项控制措施&#xff0c;以正确管理与勒索软件攻击杀伤链各阶段相关的风险。 注&#xff1a;本文节选出自《基于杀伤链的勒索软件防御指…...

Windows编程----结束进程

进程有启动就有终止&#xff0c;通过CreateProcess函数可以启动一个新的子进程&#xff0c;但是如何终结子进程呢&#xff1f;主要有四种方法&#xff1a; 通过主线程的入口函数&#xff08;main函数、WinMain函数&#xff09;的return关键字终止进程 一个应用程序只有一个入…...

三、Docker 集群管理与应用

&#xff08;一&#xff09;项目案例 1、准备主机 &#xff08;1&#xff09;关闭防火墙&#xff0c;或者开放TCP端口2377&#xff08;用于集群管理通信&#xff09;、TCP/UPD端口7946&#xff08;用于节点之间的通信&#xff09;、UDP端口4789&#xff08;用于overlay网络流…...

无标签数据增强+高效注意力GAN:基于CARLA的夜间车辆检测精度跃升

目录 一、摘要 二、引言 三、框架 四、方法 生成合成夜间数据 昼夜图像风格转换 针对夜间图像的无标签数据增强技术 五、Coovally AI模型训练与应用平台 六、实验 数据 图像风格转换 夜间车辆检测和分类 结论 论文题目&#xff1a;ENHANCING NIGHTTIME VEHICLE D…...

SqlSugar 进阶之原生Sql操作与存储过程写法 【ORM框架】

系列文章目录 &#x1f380;&#x1f380;&#x1f380; .NET开源 ORM 框架 SqlSugar 系列 &#x1f380;&#x1f380;&#x1f380; 文章目录 系列文章目录一、前言 &#x1f343;二、用法介绍三、方法列表四、使用案例五、调用存储过程六、in参数用法七、SqlServer带Go的脚…...

NO.33十六届蓝桥杯备战|函数|返回值|声明|调用|引用|函数重载(C++)

返回值 我们在设计的函数的时候&#xff0c;函数在经过计算后&#xff0c;有时候需要带回⼀些计算好的数据&#xff0c;这时候往往使⽤return 来返回&#xff0c;这⾥我们就讨论⼀下使⽤ return 返回。 return 后边可以是⼀个数值&#xff0c;也可以是⼀个表达式&#xff0c;…...

5G工业路由器赋能无人码头,港口物流智能化管理

全球贸易发展促使港口需提升运营效率&#xff0c;传统港口面临诸多难题&#xff0c;无人码头成为转型关键方向。5G 工业路由器为其提供有力通信支持&#xff0c;引领港口物流变革。 随着无人码头建设在全球兴起&#xff0c;如荷兰鹿特丹港、中国上海洋山港等。码头作业设备需实…...

机试准备第14天

首先进行树的学习。树的存储分为链式存储与顺序存储。完全二叉树是可以顺序存储的&#xff0c;将各个节点从上往下&#xff0c;从左往右存储。 第一题是找位置&#xff0c;好兄弟给的一道题&#xff0c;一遍过了。 #include <stdio.h> #include <map> #include &…...

【Academy】OAuth 2.0 身份验证漏洞 ------ OAuth 2.0 authentication vulnerabilities

OAuth 2.0 身份验证漏洞 ------ OAuth 2.0 authentication vulnerabilities 1. 什么是 OAuth&#xff1f;2. OAuth 2.0 是如何工作的&#xff1f;3. OAuth 授权类型3.1 OAuth 范围3.2 授权代码授权类型3.3 隐式授权类型 4. OAuth 身份验证4.1 识别 OAuth 身份验证4.2 侦察OAuth…...

有关Java中的多线程

学习目标 ● 掌握线程相关概念 ● 掌握线程的基本使用 ● 掌握线程池的使用 ● 了解解决线程安全方式 1.为什么要学习线程? ● 从1946年2月14日世界上第一台计算机在美国宾夕法尼亚大学诞生到今天&#xff0c;计算和处理的模式早已从单用户单任务的串行模式发展到了多用户多…...

【eNSP实战】配置交换机端口安全

拓扑图 目的&#xff1a;让交换机端口与主机mac绑定&#xff0c;防止私接主机。 主机PC配置不展示&#xff0c;按照图中配置即可。 开始配置之前&#xff0c;使用PC1 ping 一遍PC2、PC3、PC4、PC5&#xff0c;让交换机mac地址表刷新一下记录。 LSW1查看mac地址表 LSW1配置端…...

MAC-禁止百度网盘自动升级更新

通过终端禁用更新服务(推荐)​ 此方法直接移除百度网盘的自动更新组件,无需修改系统文件。 ​步骤: ​1.关闭百度网盘后台进程 按下 Command + Space → 输入「活动监视器」→ 搜索 BaiduNetdisk 或 UpdateAgent → 结束相关进程。 ​2.删除自动更新配置文件 打开终端…...

LLMs基础学习(一)概念、模型分类、主流开源框架介绍以及模型的预训练任务

文章目录 LLM基础学习&#xff08;一&#xff09;一、大语言模型&#xff08;LLMs&#xff09;的简单介绍定义与基本信息核心特点局限性参考的模型 二、大语言模型&#xff08;LLMs&#xff09;名称后 “175B”“60B”“540B” 等数字的含义数字代表模型参数数量具体示例参数数…...

【leetcode hot 100 24】两两交换链表中的节点

解法一&#xff1a;先判断链表是否为空&#xff0c;若为空则直接返回&#xff1b;否则用left和right指向第一个和第二个节点&#xff0c;当这两个节点非空时一直执行交换。其中先判断right.nextnull&#xff0c;说明链表为偶数且已经交换完break&#xff1b;再判断right.next.n…...

软件IIC和硬件IIC的主要区别,用标准库举例!

学习交流792125321&#xff0c;欢迎一起加入讨论&#xff01; 在学习iic的时候&#xff0c;我们经常会遇到软件 IC和硬件 IC,它两到底有什么区别呢&#xff1f; 软件 IC&#xff08;模拟 IC&#xff09;和硬件 IC&#xff08;外设 IC&#xff09;是两种实现 IC 总线通信的方式…...

Codeforces Round 1006 Div3 A-E

A 题目描述 夏目章人&#xff08;Natsume Akito&#xff09;刚刚在一个新世界苏醒&#xff0c;便立即收到了他的第一个任务&#xff01;系统为他提供了一个包含 n 个零的数组 a&#xff0c;以及两个整数 k 和 p。在每次操作中&#xff0c;章人需要选择两个整数 i 和 x&#x…...

4个 Vue 路由实现的过程

大家好&#xff0c;我是大澈&#xff01;一个喜欢结交朋友、喜欢编程技术和科技前沿的老程序员&#x1f468;&#x1f3fb;‍&#x1f4bb;&#xff0c;关注我&#xff0c;科技未来或许我能帮到你&#xff01; Vue 路由相信朋友们用的都很熟了&#xff0c;但是你知道 Vue 路由…...

git文件过大导致gitea仓库镜像推送失败问题解决(push failed: context deadline exceeded)

问题描述&#xff1a; 今天发现gitea仓库推送到某个镜像仓库的操作几个月前已经报错终止推送了&#xff0c;报错如下&#xff1a; 首先翻译报错提示可知是因为git仓库大小超过1G限制。检查本地.git文件&#xff0c;发现.git文件大小已达到1.13G。确定是.git文件过大导致&…...

简要分析NETLINK_ROUTE参数

NETLINK_ROUTE时Linux内核中Netlink协议族的一个子类型&#xff0c;专用于用户空间与内核网络子系统之间的通信&#xff0c;它是实现动态网络配置&#xff08;如路由表、网络接口、地址管理&#xff09;的核心机制&#xff0c;为现代网络管理工具&#xff08;如iproute2&#x…...

Java中default关键字

1. 在 switch 语句中作为默认分支 在 switch 语句里&#xff0c;default 用于定义当所有 case 标签的值都无法匹配 switch 表达式的值时要执行的代码块。它并非强制要求&#xff0c;但使用它可以增强代码的健壮性&#xff0c;处理未预见的情况。 public class SwitchDefaultE…...

怎么利用DeepSeek进行PCB设计?

最近在琢磨利用Deepseek改善PCB的细节设计&#xff0c;毕竟立创EDA里面没有集成DS&#xff0c;因此&#xff0c;如何让DS能识别图片成了重中之重。所幸最近腾讯元宝里面集成了R1的满血版&#xff0c;这个版本可以上传图片&#xff0c;于是让DS识别图片就可能了。 在原理图设计…...

详细介绍 Jupyter nbconvert 工具及其用法:如何将 Notebook 转换为 Python 脚本

nbconvert 是 Jupyter 提供的一个非常强大的工具&#xff0c;允许用户将 Jupyter Notebook 文件&#xff08;.ipynb&#xff09;转换成多种格式&#xff0c;包括 Python 脚本&#xff08;.py&#xff09;、HTML、PDF、LaTeX 等。你可以通过命令行来运行 nbconvert&#xff0c;也…...

windows上传uniapp打包的ipa文件到app store构建版本

uniapp是一个跨平台的框架&#xff0c;使用windows电脑也可以开发ios软件&#xff0c;因为uniapp的打包是在云端实现的&#xff0c;本地电脑无需使用mac电脑即可完成打包。 但是打包后的ipa文件需要上架到app store的构建版本上&#xff0c;没有mac电脑&#xff0c;又如何上架…...

PySide(PyQT),QGraphicsItem的pos()和scenePos()区别

在QGraphicsItem中&#xff0c;pos()和scenePos()是两个重要的方法&#xff0c;用于描述图形项的位置&#xff0c;但它们的含义和用途有所不同。理解它们的区别对于正确操作和管理QGraphicsItem的位置至关重要。 1. pos()方法 • 定义&#xff1a;pos()返回的是QGraphicsItem在…...

idea 快捷键 Reformat code

Reformat code...

Spring Boot 项目中使用责任链模式实现复杂接口解耦和动态编排(带示例)

目录 责任链模式概述 解耦 动态编排 运用场景 代码示例 1. 定义请求和响应对象 2. 定义处理者接口和抽象处理者类 3. 实现具体的处理者类 4. 配置责任链 5. 控制器类调用责任链 代码解释 责任链模式概述 责任链模式是一种行为设计模式,它允许你将请求沿着处理者链…...

消防设施操作员考试备考:以技巧为翼,翱翔知识天空​

消防设施操作员考试的备考过程中&#xff0c;掌握实用技巧能让学习事半功倍。以下为您介绍一系列备考技巧&#xff0c;助您在知识的天空中自由翱翔。​ 记忆技巧&#xff1a;化繁为简​ 消防知识众多&#xff0c;记忆难度较大。可以采用多种记忆方法&#xff0c;如口诀记忆法…...

qt之No executable specified

在Qt中遇到文件复制操作时出现“No executable specified”错误&#xff0c;通常与程序编译或运行环境配置问题相关&#xff0c;而非文件操作本身的问题。以下是可能的原因及解决方案&#xff1a; 项目配置文件损坏 现象&#xff1a; 在执行文件操作前&#xff0c;程序无法启动…...