python re正则模块
十分想念顺店杂可。。。
Python 的re
模块是标准库中用于处理正则表达式的核心工具,用于字符串的匹配、查找、替换、分割等复杂文本处理场景。正则表达式(Regular Expression)是一种描述字符串模式的语法,可高效实现对文本的规则性操作。
一、基础使用步骤
- 导入模块:
import re
- 定义模式:用字符串描述匹配规则(需遵循正则语法)。
- 调用函数:使用
re
模块的函数(如match
、search
、findall
等)执行匹配操作。
二、核心函数与用法
1. 匹配与查找
re.match(pattern, string, flags=0)
- 功能:从字符串开头匹配模式,若开头不匹配则返回
None
。 - 返回值:匹配成功返回
Match
对象(包含匹配信息),失败返回None
。
示例:
import re# 匹配以"hello"开头的字符串
result = re.match(r"hello", "hello world")
print(result) # <re.Match object; span=(0, 5), match='hello'>
print(result.group()) # 获取匹配内容:hello
print(result.span()) # 获取匹配位置:(0, 5)
re.search(pattern, string, flags=0)
- 功能:在整个字符串中查找第一个匹配项(不要求从开头开始)。
- 区别:与
match
的核心差异是search
不限制开头,只要字符串中存在匹配即可。
示例:
# 在字符串中查找"world"
result = re.search(r"world", "hello world")
print(result.group()) # world
print(result.span()) # (6, 11)
re.findall(pattern, string, flags=0)
- 功能:查找字符串中所有匹配项,返回一个包含所有结果的列表。
示例:
# 提取字符串中所有数字
result = re.findall(r"\d+", "年龄:25,身高:180,体重:70")
print(result) # ['25', '180', '70']
re.finditer(pattern, string, flags=0)
- 功能:与
findall
类似,但返回迭代器(逐个获取Match
对象),适合处理大量匹配结果(节省内存)。
示例:
# 迭代获取所有数字及其位置
for match in re.finditer(r"\d+", "年龄:25,身高:180"):print(f"值:{match.group()},位置:{match.span()}")
# 输出:
# 值:25,位置:(3, 5)
# 值:180,位置:(9, 12)
2. 替换与分割
re.sub(pattern, repl, string, count=0, flags=0)
- 功能:将字符串中匹配
pattern
的部分替换为repl
(替换内容)。 - 参数:
count
指定替换次数(默认 0 表示全部替换)。
示例:
# 将所有数字替换为"*"
result = re.sub(r"\d+", "*", "密码:123456,验证码:789")
print(result) # 密码:*,验证码:*# 只替换第一个数字
result = re.sub(r"\d+", "*", "密码:123456,验证码:789", count=1)
print(result) # 密码:*,验证码:789
re.split(pattern, string, maxsplit=0, flags=0)
- 功能:根据
pattern
匹配的位置分割字符串,返回分割后的列表。 - 参数:
maxsplit
指定最大分割次数(默认 0 表示全部分割)。
示例:
# 用逗号或分号分割字符串
result = re.split(r"[,;]", "苹果,香蕉;橙子,西瓜")
print(result) # ['苹果', '香蕉', '橙子', '西瓜']# 只分割一次
result = re.split(r"[,;]", "苹果,香蕉;橙子,西瓜", maxsplit=1)
print(result) # ['苹果', '香蕉;橙子,西瓜']
3. 编译正则表达式:re.compile(pattern, flags=0)
- 功能:将正则模式编译为
Pattern
对象,可重复使用(提高多次匹配的效率)。
示例:
# 编译模式(只需要一次)
pattern = re.compile(r"\d+")# 重复使用编译后的对象
print(pattern.findall("身高:180")) # ['180']
print(pattern.sub("*", "体重:70")) # 体重:*
三、Match 对象常用方法
当match
或search
匹配成功时,返回的Match
对象包含以下核心方法:
group(num=0)
:返回第num
个分组的匹配内容(默认 0 返回整个匹配)。start(num=0)
:返回第num
个分组的起始位置。end(num=0)
:返回第num
个分组的结束位置(不含)。span(num=0)
:返回(start, end)
元组。
示例(分组匹配):
# 匹配"姓名:XXX,年龄:YYY"格式,提取姓名和年龄
pattern = r"姓名:(.+),年龄:(\d+)"
result = re.search(pattern, "姓名:张三,年龄:25")print(result.group(0)) # 整个匹配:姓名:张三,年龄:25
print(result.group(1)) # 第一个分组(姓名):张三
print(result.group(2)) # 第二个分组(年龄):25
print(result.span(2)) # 年龄的位置:(9, 11)
四、常用正则元字符(模式语法)
正则表达式通过元字符描述匹配规则,核心元字符如下:
元字符 | 含义 | 示例 |
---|---|---|
. | 匹配任意字符(除换行符,re.DOTALL 模式下可匹配换行) | r"h.t" 匹配 "hot"、"h1t" 等 |
^ | 匹配字符串开头 | r"^hello" 匹配以 "hello" 开头的字符串 |
$ | 匹配字符串结尾 | r"world$" 匹配以 "world" 结尾的字符串 |
* | 前面的字符匹配 0 次或多次(贪婪匹配) | r"ab*" 匹配 "a"、"ab"、"abb" 等 |
+ | 前面的字符匹配 1 次或多次 | r"ab+" 匹配 "ab"、"abb" 等(不匹配 "a") |
? | 前面的字符匹配 0 次或 1 次;或非贪婪匹配(加在* /+ 后) | r"ab?" 匹配 "a"、"ab";r"a.*?b" 非贪婪匹配 "a 到 b" |
{n} | 前面的字符匹配 n 次 | r"\d{3}" 匹配 3 位数字(如 "123") |
{n,m} | 前面的字符匹配 n 到 m 次 | r"\d{2,4}" 匹配 2-4 位数字(如 "12"、"1234") |
[] | 字符集,匹配其中任意一个字符 | r"[abc]" 匹配 "a"、"b" 或 "c";r"[0-9]" 匹配数字 |
() | 分组,将部分模式视为一个整体 | r"(ab)+" 匹配 "ab"、"abab" 等 |
| | 或运算,匹配左边或右边的模式 | r"cat|dog" 匹配 "cat" 或 "dog" |
\ | 转义字符,匹配元字符本身(如\. 匹配 ".") | r"www\.baidu\.com" 匹配网址 |
五、常用标志位(flags)
通过flags
参数扩展匹配规则:
re.IGNORECASE
(re.I
):忽略大小写匹配。re.MULTILINE
(re.M
):多行模式,^
/$
匹配每行开头 / 结尾。re.DOTALL
(re.S
):让.
匹配换行符。
示例(忽略大小写):
result = re.match(r"hello", "HELLO", re.IGNORECASE)
print(result.group()) # HELLO(成功匹配)
六、注意事项
- 原始字符串:正则模式建议用
r
前缀(原始字符串),避免转义字符冲突(如r"\d"
比"\\d"
更简洁)。 - 贪婪 vs 非贪婪:
*
/+
默认贪婪(尽可能多匹配),加?
变为非贪婪(尽可能少匹配)。例如r"a.*b"
匹配 "aXXbXXb" 中的 "aXXbXXb",而r"a.*?b"
只匹配 "aXXb"。 - 性能:复杂正则可能效率低,建议用
re.compile()
预编译模式,且避免过度使用通配符(如.*
)。 - 分组陷阱:
findall
中若模式有分组,会返回分组内容而非整体匹配(如需整体匹配,可将模式用(...)
包裹为一个大分组)。
七、综合示例:验证邮箱格式
import redef is_valid_email(email):# 简单邮箱正则:用户名@域名(支持字母、数字、下划线、点)pattern = r"^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"return re.match(pattern, email) is not Noneprint(is_valid_email("test@example.com")) # True
print(is_valid_email("invalid-email")) # False
更多细节可参考官方文档:re — 正则表达式操作。