Python中正则表达式(re 模块)详解使用(1)原理篇


一、正则表达式简介

正则表达式(Regular Expression, regex)是一种用于匹配、查找、替换字符串模式的强大工具。
在 Python 中由标准库 re 提供支持。

import re

二、基础语法结构

类型符号含义示例
字符匹配.匹配任意除换行外的字符a.c → 匹配 abc, axc
字符集[abc]匹配 a 或 b 或 c[0-9] 匹配任意数字
否定字符集[^abc]不匹配 a,b,c[^0-9] 非数字
转义\转义或表示特殊序列\d, \s, \w
组与范围( )捕获分组(abc)+ 匹配多次出现的 “abc”
``或逻辑`catdog` 匹配 “cat” 或 “dog”

三、量词(重复次数)

符号含义示例
*重复 0 次或多次ab*cac, abc, abbc
+重复 1 次或多次ab+cabc, abbc
?重复 0 或 1 次ab?cac, abc
{n}重复 n 次a{3}aaa
{n,}至少 n 次a{2,}aa, aaa, …
{n,m}n 到 m 次之间a{2,4}aa, aaa, aaaa

贪婪与非贪婪(懒惰)模式

类型含义示例
贪婪(默认)尽可能多地匹配a.*b 匹配最远的 b
非贪婪尽可能少地匹配a.*?b 匹配最近的 b

四、预定义字符集(快捷写法)

表达式含义等价
\d数字[0-9]
\D非数字[^0-9]
\w单词字符(字母数字下划线)[A-Za-z0-9_]
\W非单词字符[^A-Za-z0-9_]
\s空白字符(空格、制表、换行等)[ \t\n\r\f\v]
\S非空白字符[^ \t\n\r\f\v]

五、锚点(位置匹配)

符号含义示例
^字符串开头^abc 匹配以 abc 开头
$字符串结尾abc$ 匹配以 abc 结尾
\b单词边界\bcat\b 仅匹配独立单词 “cat”
\B非单词边界\Bcat\B

六、分组与反向引用

捕获分组

m = re.match(r'(\d{4})-(\d{2})-(\d{2})', '2025-10-31')
print(m.group(1))  # 2025
print(m.group(2))  # 10
print(m.group(3))  # 31

命名分组

m = re.match(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})', '2025-10-31')
print(m.group('year'))  # 2025

反向引用

re.search(r'(\b\w+)\s+\1', 'hello hello world')  # 匹配重复单词

七、前瞻与后顾(零宽断言)

类型写法含义示例
正向前瞻(?=...)匹配后面满足条件的字符串\d(?=px) 匹配 “12px” 中的 “2”
负向前瞻(?!...)匹配后面不满足条件的字符串\d(?!px)
正向后顾(?<=...)匹配前面满足条件的字符串(?<=\$)\d+ 匹配 “$99” 中的 “99”
负向后顾(?<!...)匹配前面不满足条件的字符串(?<!\$)\d+

这些不会消耗字符,因此称为零宽断言


八、re 模块常用函数

函数作用示例
re.match()从字符串开头匹配re.match('abc', 'abcdef')
re.search()搜索任意位置首次匹配re.search('abc', '123abc456')
re.findall()返回所有匹配的列表re.findall(r'\d+', 'a1b22c333') → ['1','22','333']
re.finditer()返回迭代器,每个元素是 Match 对象遍历效率高
re.sub()替换匹配字符串re.sub(r'\d+', '#', 'a1b22c333') → 'a#b#c#'
re.split()按匹配模式分割re.split(r'[,;]', 'a,b;c') → ['a','b','c']
re.compile()预编译正则,重复使用时更高效pattern = re.compile(r'\d+')

九、匹配对象 Match 属性

m = re.search(r'(\d+)', 'abc123xyz')
m.group()    # '123'
m.start()    # 3
m.end()      # 6
m.span()     # (3,6)
m.groups()   # ('123',)

十、标志位(flags)

Flag含义示例
re.I忽略大小写re.match(r'abc', 'ABC', re.I)
re.M多行模式 (^,$ 匹配行首行尾)re.findall('^abc', text, re.M)
re.S. 匹配换行符re.findall('a.*b', s, re.S)
re.X允许正则表达式中写注释(verbose 模式)re.compile(r''' \d+ # 数字 ''', re.X)
re.UUnicode 模式(Python 3 默认开启)处理中文时生效

十一、典型应用示例

提取邮箱地址

re.findall(r'[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}', text)

提取日期

re.findall(r'\d{4}-\d{2}-\d{2}', 'Today is 2025-10-31.')

提取 HTML 标签内容

re.findall(r'<title>(.*?)</title>', html, re.S)

匹配 IP 地址

re.findall(r'\b(?:\d{1,3}\.){3}\d{1,3}\b', text)

替换多余空格

re.sub(r'\s+', ' ', text)

十二、性能与优化建议

优化点建议
🔹 重复匹配使用 re.compile() 预编译模式
🔹 贪婪匹配过慢改为非贪婪模式 .*?
🔹 多分支匹配使用非捕获组 `(?:abc)`
🔹 大文本匹配优先使用 finditer() 而非 findall()
🔹 正则太复杂可考虑分步匹配或 string 方法替代

十三、特殊用法

非捕获分组

(?:abc){2}     # 匹配两次abc,但不捕获

条件匹配

(?(1)then|else)  # 若第1组存在则匹配then,否则匹配else

注释正则(verbose 模式)

pattern = re.compile(r'''
    ^\s*             # 开头空白
    ([A-Za-z_]\w*)   # 标识符
    \s*=\s*          # 等号
    (".*?"|\d+)      # 字符串或数字
''', re.X)

十四、示例汇总演示

import re

text = "Name: Tom, Email: tom@example.com, Age: 25"

# 1. 提取邮箱
email = re.search(r'[\w.-]+@[\w.-]+\.\w+', text).group()

# 2. 提取数字
nums = re.findall(r'\d+', text)

# 3. 替换名字
new_text = re.sub(r'Tom', 'Jerry', text)

# 4. 按逗号分割
parts = re.split(r',\s*', text)

# 5. 使用预编译
pat = re.compile(r'\b[A-Z][a-z]+\b')
names = pat.findall("Tom and Alice went to London.")

十五、参考正则速查表(Cheat Sheet)

.        任意字符
^ $      行首/行尾
\d \D    数字/非数字
\s \S    空白/非空白
\w \W    单词字符/非单词
[...]    字符集
[^...]   非字符集
(a|b)    或
(...)    捕获组
(?:...)  非捕获组
(?P<name>...) 命名捕获组
(?=...)  正向前瞻
(?!...)  负向前瞻
(?<=...) 正向后顾
(?<!...) 负向后顾
{m,n}    重复m~n次
* + ?    0+ / 1+ / 0-1 次
*? +? ?? 懒惰匹配
\b \B    单词边界 / 非边界

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云SLAM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值