🎯 Python正则表达式re模块完全指南:从入门到实战
正则表达式(Regular Expression)是处理文本数据的利器,堪称程序员的"瑞士军刀"。Python的re模块提供了完整的正则表达式支持,让你能够高效地进行字符串匹配、查找、替换和分割。本文将带你全面掌握re模块的核心用法。
一、什么是正则表达式?
正则表达式是一种用于描述字符串匹配规则的语法。通过定义特定的模式(Pattern),我们可以:
- 🔍 查找符合特定格式的文本
- ✂️ 从复杂字符串中提取有用信息
- 🔄 批量替换文本内容
- 📊 验证用户输入的有效性
二、re模块核心函数详解
1. re.match() - 从头匹配
match()函数从字符串开头开始匹配,如果开头不匹配则返回None。
import re
# 匹配以Hello开头的字符串
pattern = r'Hello'
text = 'Hello, World!'
result = re.match(pattern, text)
if result:
print(f"匹配成功: {result.group()}") # 输出: Hello
else:
print("匹配失败")
# 尝试匹配不在开头的模式
text2 = 'Say Hello'
result2 = re.match(pattern, text2)
print(result2) # 输出: None
2. re.search() - 全局搜索
search()在整个字符串中搜索第一个匹配的子串。
text = 'Python is great, Python is easy'
result = re.search(r'Python', text)
print(result.group()) # 输出: Python(第一个)
3. re.findall() - 查找所有匹配
返回所有匹配项的列表。
text = '2024年3月15日,天气晴朗,温度25°C'
numbers = re.findall(r'\d+', text)
print(numbers) # 输出: ['2024', '3', '15', '25']
4. re.finditer() - 迭代器方式查找
返回一个迭代器,适合处理大量匹配结果。
text = 'Python3.9和Python3.10都很棒'
for match in re.finditer(r'Python\d\.\d+', text):
print(f"找到: {match.group()},位置: {match.span()}")
5. re.sub() - 替换文本
强大的字符串替换功能。
text = '电话:138-1234-5678,备用:139-8765-4321'
# 隐藏中间四位
hidden = re.sub(r'(\d{3})-\d{4}-(\d{4})', r'\1-****-\2', text)
print(hidden) # 输出: 电话:138-****-5678,备用:139-****-4321
6. re.split() - 分割字符串
根据匹配模式分割字符串。
text = 'apple,banana;orange|grape'
fruits = re.split(r'[,;|]', text)
print(fruits) # 输出: ['apple', 'banana', 'orange', 'grape']
7. re.compile() - 编译正则
对于重复使用的模式,先编译可以提高性能。
# 编译邮箱模式
email_pattern = re.compile(r'^[\w\.-]+@[\w\.-]+\.\w+$')
# 多次使用
print(email_pattern.match('user@example.com')) # 匹配
print(email_pattern.match('invalid.email')) # 不匹配
三、正则表达式语法精要
1. 常用元字符
| 元字符 | 含义 | 示例 |
|---|---|---|
. |
匹配任意字符(除换行) | a.c → abc, a1c |
^ |
匹配字符串开头 | ^Hello → 以Hello开头 |
$ |
匹配字符串结尾 | world$ → 以world结尾 |
\d |
匹配数字 | \d{3} → 三位数字 |
\w |
匹配字母/数字/下划线 | \w+ → 一个或多个单词字符 |
\s |
匹配空白字符 | \s+ → 一个或多个空格 |
\b |
单词边界 | \bword\b → 完整单词 |
2. 量词控制
# * 零次或多次
re.findall(r'bo*k', 'bk bok book') # ['bk', 'bok', 'book']
# + 一次或多次
re.findall(r'bo+k', 'bk bok book') # ['bok', 'book']
# ? 零次或一次
re.findall(r'colou?r', 'color colour') # ['color', 'colour']
# {n,m} n到m次
re.findall(r'\d{2,4}', '1 12 123 1234 12345') # ['12', '123', '1234', '1234']
3. 贪婪与非贪婪
text = '
内容1
内容2
'
# 贪婪匹配(默认)- 尽可能匹配更多
re.findall(r'
.*
', text) # ['
内容1
内容2
']
# 非贪婪匹配 - 尽可能匹配更少
re.findall(r'
.*?
', text) # ['
内容1
', '
内容2
']
4. 分组与捕获
text = '2024-03-15'
# 使用括号分组
pattern = r'(\d{4})-(\d{2})-(\d{2})'
match = re.search(pattern, text)
if match:
print(f"年: {match.group(1)}") # 2024
print(f"月: {match.group(2)}") # 03
print(f"日: {match.group(3)}") # 15
四、实用案例集锦
案例1:邮箱验证
def validate_email(email):
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email))
# 测试
print(validate_email('user@example.com')) # True
print(validate_email('invalid@.com')) # False
案例2:手机号提取(支持多种格式)
def extract_phones(text):
# 支持 138-1234-5678、13812345678、(138)1234-5678 等格式
pattern = r'(?:\+?86[-\s]?)?(?:1[3-9]\d[-\s]?\d{4}[-\s]?\d{4}|\(1[3-9]\d\)\s?\d{4}[-\s]?\d{4})'
phones = re.findall(pattern, text)
# 统一格式
return [re.sub(r'\D', '', p)[-11:] for p in phones]
text = '联系:138-1234-5678 或 (139)8765-4321'
print(extract_phones(text)) # ['13812345678', '13987654321']
案例3:日志解析
log_line = '2024-03-15 14:30:25 [ERROR] Connection failed: timeout'
pattern = r'(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \[(\w+)\] (.+)'
match = re.match(pattern, log_line)
if match:
log_entry = {
'date': match.group(1),
'time': match.group(2),
'level': match.group(3),
'message': match.group(4)
}
print(log_entry)
案例4:URL参数解析
from urllib.parse import unquote
def parse_url_params(url):
# 提取查询字符串
match = re.search(r'\?(.+)$', url)
if not match:
return {}
params = {}
for param in match.group(1).split('&'):
if '=' in param:
key, value = param.split('=', 1)
params[unquote(key)] = unquote(value)
return params
url = 'https://example.com/search?q=python&lang=zh&page=1'
print(parse_url_params(url))
# {'q': 'python', 'lang': 'zh', 'page': '1'}
五、性能优化建议
1. 预编译重复使用的模式
# ❌ 不推荐:每次循环都编译
for email in email_list:
if re.match(r'^[
\w\.-]+@[\w\.-]+\.\w+$', email):
process(email)
# ✅ 推荐:先编译再使用
email_pattern = re.compile(r'^[\w\.-]+@[\w\.-]+\.\w+$')
for email in email_list:
if email_pattern.match(email):
process(email)
2. 使用原始字符串避免转义
# ❌ 容易出错
pattern = 'C:\\Users\\Name'
# ✅ 更清晰
pattern = r'C:\Users\Name'
3. 避免过度复杂的正则
# 更好的方式:分步骤验证
def validate_complex_input(text):
if not re.match(r'^\w{3,20}$', text):
return False
if not re.search(r'\d', text): # 必须包含数字
return False
if not re.search(r'[A-Z]', text): # 必须包含大写字母
return False
return True
六、总结
Python的re模块提供了强大的正则表达式功能:
match()- 从开头匹配search()- 全局搜索首个匹配findall()- 返回所有匹配列表finditer()- 返回匹配迭代器sub()- 替换匹配内容split()- 按模式分割compile()- 预编译模式
掌握正则表达式,你将能够优雅地处理各种文本处理任务。记住:正则表达式是一把双刃剑,适度的正则简洁高效,过度的正则难以维护。在使用时要平衡简洁性与可读性。
参考资料
💡 小提示:复杂的正则表达式建议先在 Regex101 等在线工具中测试,确认无误后再写入代码!

浙公网安备 33010602011771号