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

Python 正则表达式完全指南:从基础语法到实战案例

正则表达式(Regular Expression)是处理字符串匹配、提取、替换的强大工具,在数据清洗、表单验证、文本分析等场景中应用广泛。本文基于 Python 的 re 模块,结合基础语法与实战案例,带你系统掌握正则表达式的使用方法。


一、正则表达式基础语法

正则表达式的核心是 “匹配模式”,通过特定符号组合定义规则,匹配符合条件的字符串。以下是常用语法分类总结:

1. 精确匹配与选择匹配

  • 精确匹配:直接写目标字符串,匹配完全一致的内容。
    示例:red 仅匹配字符串 "red"。
  • 选择匹配:用 | 分隔多个选项,匹配任意一个选项。
    示例:red|yellow|blue 匹配 "red"、"yellow" 或 "blue"。

2. 模糊匹配(字符集与元字符)

当需要匹配 “某一类字符” 时,使用字符集或元字符(元字符是字符集的简化写法)。

(1)字符集 [ ]
  • [abc]:匹配 "a"、"b"、"c" 中的任意一个字符。
  • [^abc]:匹配除 "a"、"b"、"c" 以外的任意字符(^ 表示 “非”)。
  • [0-9]:匹配 0-9 中的任意一个数字。
  • [a-z]/[A-Z]:匹配小写 / 大写英文字母。
  • [A-z]:匹配英文字母(含大小写)或下划线 _(注意:ASCII 表中 Z 与 a 之间有特殊字符,实际推荐用 [a-zA-Z_])。
  • [\u4e00-\u9fa5]:匹配任意一个中文汉字(Python 支持 Unicode 编码)。
(2)元字符

元字符是字符集的 “简写形式”,更简洁高效:

元字符含义等价字符集
\d匹配数字[0-9]
\D匹配非数字[^0-9]
\w匹配字母、数字、下划线[a-zA-Z0-9_]
\W匹配非字母、数字、下划线[^a-zA-Z0-9_]
.匹配除换行符 \n 外的任意字符-
`\d\D`匹配任意字符(包括换行符)-

3. 量词:控制匹配次数

量词用于定义 “前面的字符 / 表达式需要匹配多少次”,解决 “重复匹配” 问题:

量词含义示例
re{n}匹配 re 恰好 n 次\d{3} 匹配 3 位数字(如 "123")
re{n,}匹配 re 至少 n 次\d{2,} 匹配 2 位及以上数字(如 "12"、"123")
re{n,m}匹配 re 至少 n 次、最多 m 次\d{2,4} 匹配 2-4 位数字(如 "12"、"1234")
re?匹配 re 0 次或 1 次(可选)ab? 匹配 "a" 或 "ab"
re+匹配 re 1 次或多次\d+ 匹配 1 位及以上数字
re*匹配 re 0 次或多次a* 匹配 ""、"a"、"aa" 等
贪婪匹配与非贪婪匹配
  • 贪婪匹配:默认行为,尽可能多匹配(“能多不少”)。
    示例:\d{2,4} 匹配 "12345" 时,会优先匹配 4 位数字 "1234"。
  • 非贪婪匹配:在量词后加 ?,尽可能少匹配(“能少不多”)。
    示例:\d{2,4}? 匹配 "12345" 时,会优先匹配 2 位数字 "12"。

4. 限定符:锚定匹配位置

限定符用于定义 “匹配的字符串必须在什么位置”,常见的有:

  • ^:匹配字符串的开头
    示例:^abc 仅匹配以 "abc" 开头的字符串(如 "abc123",不匹配 "123abc")。
  • $:匹配字符串的结尾
    示例:abc$ 仅匹配以 "abc" 结尾的字符串(如 "123abc",不匹配 "abc123")。
  • ^abc$:精确匹配整个字符串(只能是 "abc",长度和内容完全一致)。

5. 分组:提取与复用匹配结果

用 () 对正则表达式分组,可实现 “提取子结果” 和 “复用匹配规则”。

(1)普通分组

每个 () 对应一个分组,分组索引从 1 开始(0 是整个匹配结果)。
示例:(\d{2})([a-z]+) 匹配 "12ab" 时,分组 1 是 "12",分组 2 是 "ab"。

(2)命名捕获分组

用 (?P<name>re) 给分组命名,后续可通过名称获取结果(更易读)。
示例:(?P<year>\d{4})-(?P<month>\d{2}) 匹配 "2024-05" 时,可通过 "year" 获取 "2024","month" 获取 "05"。

(3)非捕获分组

用 (?:re) 取消分组的 “捕获功能”(仅用于分组匹配,不单独提取结果)。
示例:(?:abc)|(?:def) 匹配 "abc" 或 "def",但不单独捕获分组结果。

(4)反向引用

用 \n(n 是分组索引)复用前面分组的匹配结果,常用于匹配 “重复模式”。
示例:

  • (.)(.)\1\2 匹配 "ABAB" 类型(如 "abab"、"1212")。
  • (.)\1(.)\2 匹配 "AABB" 类型(如 "aabb"、"1122")。

6. 断言:有条件的匹配

断言是 “附加条件的匹配”,不消耗字符,仅判断条件是否满足(也叫 “零宽断言”)。

断言类型语法含义示例
正向确定断言re(?=rex)匹配后面是 rex 的 re\d+(?=px) 匹配 "12px" 中的 "12"
正向否定断言re(?!rex)匹配后面不是 rex 的 re\d+(?!px) 匹配 "12cm" 中的 "12"
反向确定断言(?<=rex)re匹配前面是 rex 的 re(?<=¥)\d+ 匹配 "¥100" 中的 "100"
反向否定断言(?<!rex)re匹配前面不是 rex 的 re(?<!¥)\d+ 匹配 "$100" 中的 "100"

7. 经典案例:密码强度验证

需求:密码必须包含数字、大小写字母、特殊符号(!@#$%^&*),长度 8-18 位。
正则表达式:^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]).{8,18}$
解析:

  • (?=.*[0-9]):确保包含至少一个数字。
  • (?=.*[a-z]):确保包含至少一个小写字母。
  • (?=.*[A-Z]):确保包含至少一个大写字母。
  • (?=.*[!@#$%^&*]):确保包含至少一个特殊符号。
  • .{8,18}:匹配 8-18 位任意字符(除换行符)。
  • ^ 和 $:锚定整个字符串,避免前后有多余字符。

二、Python re 模块核心方法

Python 的 re 模块提供了正则表达式的核心操作,以下是常用方法的详解与示例。

1. match(pattern, string, flags=0)

  • 功能:从字符串开头匹配,若开头不匹配则返回 None,匹配成功返回 Match 对象。
  • 参数
    • pattern:正则表达式(字符串或编译后的对象)。
    • string:待匹配的字符串。
    • flags:匹配模式(如 re.I 忽略大小写,re.S 让 . 匹配换行符)。

示例

import re# 命名捕获分组示例
res = re.match(r'(?P<first>\d{2})(?P<second>\d{2})', '1234ab')
print(res.span())       # 返回匹配区间 (0, 4)(匹配了前4个字符 "1234")
print(res.groups())     # 返回所有分组元组 ('12', '34')
print(res.group())      # 返回整个匹配结果 '1234'
print(res.group(1))     # 返回第1个分组结果 '12'
print(res.groupdict())  # 返回命名分组字典 {'first': '12', 'second': '34'}

2. fullmatch(pattern, string, flags=0)

  • 功能:匹配整个字符串(从开头到结尾),完全符合正则才返回 Match 对象,否则返回 None
  • 场景:用于严格验证(如手机号、身份证号)。

示例

import re# 验证手机号(11位数字)
res = re.fullmatch(r'\d{11}', '12345678903abc')
print(res)  # None(字符串末尾有 "abc",不满足11位数字)res = re.fullmatch(r'\d{11}', '12345678903')
print(res)  # <re.Match object; span=(0, 11), match='12345678903'>(匹配成功)

3. findall(pattern, string, flags=0)

  • 功能:查找字符串中所有符合正则的子串,返回列表(无匹配则返回空列表)。
  • 分组影响
    • 无分组:返回所有匹配结果的列表。
    • 1 个分组:返回仅包含分组结果的列表。
    • 多个分组:返回列表,每个元素是分组结果的元组。

示例

import re# 多个分组:提取数字+字母组合
res = re.findall(r'(\d+)([a-z]+)', 'ab12cd34ef')
print(res)  # [('12', 'cd'), ('34', 'ef')](每个元组是一组数字+字母)# 无分组:提取所有数字
res = re.findall(r'\d+', 'ab12cd34ef')
print(res)  # ['12', '34']

4. search(pattern, string, flags=0)

  • 功能:在字符串中任意位置查找第一个符合正则的子串,返回 Match 对象(无匹配则返回 None)。
  • 区别于 matchmatch 仅从开头匹配,search 可匹配任意位置。

示例

import re# 查找第一个数字+字母组合
res = re.search(r'(\d+)([a-z]+)', 'ab12cd34ef')
print(res.group())    # '12cd'(整个匹配结果)
print(res.groups())   # ('12', 'cd')(分组结果)

5. sub(pattern, repl, string, count=0, flags=0)

  • 功能:替换字符串中符合正则的子串,返回替换后的新字符串。
  • 参数
    • repl:替换后的内容(字符串或函数)。
    • count:替换次数(0 表示替换所有,默认 0)。
  • 分组引用:在 repl 中用 \n(n 是分组索引)引用分组结果。

示例

import re# 替换所有数字+字母组合为 "中"
res = re.sub(r'\d+[a-z]+', '中', '12cd34ab')
print(res)  # '中中'# 手机号脱敏:13623456789 → 136****6789
res = re.sub(r'(\d{3})\d{4}(\d{4})', r'\1****\2', '13623456789')
print(res)  # '136****6789'(\1 引用前3位,\2 引用后4位)# 限制替换次数(仅替换1次)
res = re.sub(r'\d+', '中', '12cd34ab', count=1)
print(res)  # '中cd34ab'

6. subn(pattern, repl, string, count=0, flags=0)

  • 功能:与 sub 类似,但返回元组 (替换后的字符串, 替换次数)

示例

import reres = re.subn(r'\d+', '中', '12cd34ab')
print(res)  # ('中cd中ab', 2)(替换后的字符串 + 替换了2次)

三、实战:任务清单表单验证

结合正则表达式与 re 模块,实现任务清单中的表单验证功能(如手机号、邮箱、任务名长度):

import redef validate_phone(phone):"""验证手机号(11位数字)"""pattern = r'^\d{11}$'return bool(re.fullmatch(pattern, phone))def validate_email(email):"""验证邮箱(如 xxx@xxx.com)"""pattern = r'^\w+@\w+(\.[a-zA-Z]{2,3}){1,2}$'return bool(re.fullmatch(pattern, email))def validate_task_name(name):"""验证任务名(1-50位字符,不包含特殊符号)"""pattern = r'^[a-zA-Z0-9\u4e00-\u9fa5]{1,50}$'return bool(re.fullmatch(pattern, name))# 测试
print(validate_phone('13623456789'))  # True
print(validate_email('test@163.com')) # True
print(validate_task_name('学习正则表达式!')) # False(包含特殊符号 "!")

四、常见问题与注意事项

  1. 转义字符问题:Python 字符串中的 \ 需要转义(如 \d 需写为 r'\d' 或 '\\d'),推荐用 原始字符串 r'' 避免转义麻烦。
  2. 匹配模式 flags
    • re.I:忽略大小写(如 re.match(r'abc', 'ABC', re.I) 匹配成功)。
    • re.S:让 . 匹配换行符(默认不匹配)。
    • re.M:多行模式(让 ^/$ 匹配每行的开头 / 结尾)。
  3. 性能优化:频繁使用的正则表达式,用 re.compile(pattern) 编译为对象,可提高执行效率。
http://www.dtcms.com/a/356134.html

相关文章:

  • 深入理解文本向量嵌入(Vector Embeddings):原理、实践与应用场景
  • Linux---gdb和cgdb
  • UML状态图中entry/do/exit动作的深入解析与C/C++实现
  • 《深度讲解 C 语言动态内存:函数用法、错误规避与经典笔试题》
  • 同类软件对比(二):VS Code 与 PyCharm 的 Python 开发对比与使用建议
  • JavaScript初识:给小白的第一堂编程课
  • Day20 常见降维算法
  • 沙箱操作工具
  • 机器学习(讲解)
  • ROS2 入门实战 —— 从环境搭建到第一次控制小乌龟(一)
  • 【电子设计自动化(EDA)】Altium Designer25——电子设计自动化(EDA)软件版保姆级下载安装详细图文教程(附安装包)
  • linux网络编程-----TCP服务端并发模型(epoll)
  • [数组]27.移除元素
  • SQLServer日志文件损坏恢复办法
  • day13(练习题)
  • 卷积核尺寸如何计算?
  • Containerd卸载指南
  • shell脚本编程规范与变量
  • Shell 入门
  • LeetCode刷题记录----35.搜索插入位置(Easy)
  • 117、【OS】【Nuttx】【周边】效果呈现方案解析:while 循环处理(下)
  • 虚拟机逃逸攻防演练技术文章大纲
  • 八个按键一一对应八个输出
  • C语言————斐波那契数列(例题1)
  • BoardSim仿真
  • DoIP路由激活报文
  • Shell脚本(2)
  • 洛谷p1028数的计算 详解
  • 【智能体】零代码学习 Coze 智能体(1)
  • 人工智能基础概念