比较详细Python正则表达式操作指南
《比较详细Python正则表达式操作指南》
正则表达式(Regular Expression)是处理文本数据的强大工具,通过模式匹配实现复杂字符串的搜索、替换和提取。在Python中,`re`模块提供了完整的正则表达式支持,能够高效处理日志分析、数据清洗、爬虫开发等场景。本文将从基础语法到高级技巧,系统讲解Python正则表达式的核心操作。
一、正则表达式基础语法
正则表达式由普通字符和特殊元字符组成,通过组合构建匹配模式。
1. 普通字符与转义
字母、数字和部分符号(如`_`)直接匹配自身,特殊字符需用反斜杠`\`转义:
import re
text = "Price: $19.99"
pattern = r"\$" # 匹配$符号
match = re.search(pattern, text)
print(match.group()) # 输出: $
2. 字符集与范围
使用`[]`定义字符集合,匹配其中任意一个字符:
- `[abc]`:匹配a、b或c
- `[a-z]`:匹配任意小写字母
- `[0-9A-Za-z]`:匹配数字或字母
text = "Contact: 123-456-7890"
pattern = r"[\d-]+" # 匹配数字和连字符
result = re.findall(pattern, text)
print(result) # 输出: ['123-456-7890']
3. 量词控制
通过量词指定字符出现次数:
- `*`:0次或多次
- `+`:1次或多次
- `?`:0次或1次
- `{n}`:恰好n次
- `{n,m}`:n到m次
text = "aaabbbccc"
pattern1 = r"a{3}" # 匹配3个a
pattern2 = r"b{1,2}" # 匹配1或2个b
print(re.search(pattern1, text).group()) # 输出: aaa
print(re.findall(pattern2, text)) # 输出: ['bb']
4. 边界匹配
控制匹配的起始和结束位置:
- `^`:匹配字符串开头
- `$`:匹配字符串结尾
- `\b`:单词边界
text = "Python is awesome"
pattern1 = r"^Python" # 开头匹配
pattern2 = r"awesome$" # 结尾匹配
pattern3 = r"\bis\b" # 匹配独立单词is
print(re.search(pattern1, text).group()) # 输出: Python
print(re.search(pattern3, text).group()) # 输出: is
二、Python re模块核心方法
`re`模块提供多个函数处理正则表达式,常用方法包括搜索、匹配、替换和分割。
1. re.match() 与 re.search()
`match()`从字符串开头匹配,`search()`扫描整个字符串:
text = "2023-01-15"
match_obj = re.match(r"\d{4}", text) # 从开头匹配4位数字
search_obj = re.search(r"\d{2}-\d{2}", text) # 搜索日期格式
print(match_obj.group()) # 输出: 2023
print(search_obj.group()) # 输出: 01-15
2. re.findall() 与 re.finditer()
`findall()`返回所有匹配的子串列表,`finditer()`返回迭代器:
text = "cat1 dog2 cat3"
patterns = re.findall(r"cat\d", text) # 匹配cat+数字
iter_obj = re.finditer(r"dog\d", text) # 返回匹配对象迭代器
print(patterns) # 输出: ['cat1', 'cat3']
for match in iter_obj:
print(match.group()) # 输出: dog2
3. re.sub() 替换文本
使用`sub()`替换匹配的文本,支持函数式替换:
text = "The price is $100"
new_text = re.sub(r"\$\d+", "$$$", text) # 替换价格标记
print(new_text) # 输出: The price is $$$
# 函数式替换
def double_num(match):
num = int(match.group(1))
return f"${num*2}"
text = "Cost: $50"
result = re.sub(r"\$(\d+)", double_num, text)
print(result) # 输出: Cost: $100
4. re.split() 分割字符串
根据正则模式分割字符串:
text = "apple,banana;orange"
split_result = re.split(r"[,;]", text) # 按逗号或分号分割
print(split_result) # 输出: ['apple', 'banana', 'orange']
三、高级正则技巧
掌握分组、非贪婪匹配和预编译等技巧可提升正则效率。
1. 分组与捕获
使用`()`定义分组,通过`group(n)`获取特定分组:
text = "Date: 2023-12-25"
pattern = r"(\d{4})-(\d{2})-(\d{2})"
match = re.search(pattern, text)
if match:
print(match.group(1)) # 输出: 2023 (年)
print(match.group(2)) # 输出: 12 (月)
print(match.groups()) # 输出所有分组: ('2023', '12', '25')
2. 非贪婪匹配
在量词后加`?`实现非贪婪匹配(尽可能短匹配):
text = "content1
content2"
greedy = re.search(r".*", text) # 贪婪匹配
non_greedy = re.search(r".*?", text) # 非贪婪匹配
print(greedy.group()) # 输出: content1
content2
print(non_greedy.group()) # 输出: content1
3. 预编译正则表达式
频繁使用的正则表达式可预编译提升性能:
import re
email_pattern = re.compile(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")
emails = ["user@example.com", "invalid@.com"]
for email in emails:
if email_pattern.fullmatch(email):
print(f"Valid: {email}")
else:
print(f"Invalid: {email}")
4. 常用元字符速查表
元字符 | 含义 |
---|---|
`\d` | 数字字符 |
`\w` | 单词字符(字母、数字、下划线) |
`\s` | 空白字符(空格、制表符、换行) |
`\D` | 非数字字符 |
`\W` | 非单词字符 |
`\S` | 非空白字符 |
四、实战案例解析
通过实际案例掌握正则表达式的综合应用。
案例1:提取日志中的错误信息
log = """
2023-01-01 ERROR: Database connection failed
2023-01-02 INFO: User logged in
2023-01-03 ERROR: Invalid credentials
"""
pattern = r"\d{4}-\d{2}-\d{2} ERROR: (.+)"
errors = re.findall(pattern, log)
print(errors) # 输出: ['Database connection failed', 'Invalid credentials']
案例2:验证密码强度
def validate_password(password):
pattern = r"^(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$"
return bool(re.fullmatch(pattern, password))
print(validate_password("Passw0rd!")) # 输出: True
print(validate_password("weakpass")) # 输出: False
案例3:爬取网页中的链接
import re
html = """
Example
About
"""
links = re.findall(r'', html)
print(links) # 输出: ['https://example.com', '/about']
五、常见问题与调试技巧
正则表达式编写中易犯错误及调试方法。
1. 贪婪匹配导致的过度匹配
问题:`.*`会匹配到最后一个可能的结束位置
解决:使用非贪婪模式`.*?`或明确边界
2. 转义字符遗漏
问题:未转义的特殊字符导致匹配失败
解决:使用原始字符串(`r"..."`)或双重转义
3. 调试工具推荐
- 在线工具:regex101.com、regexper.com
- Python调试:`re.DEBUG`标志打印解析树
pattern = re.compile(r"(\d+)-(\w+)", re.DEBUG)
# 输出解析树信息
六、性能优化建议
提升正则表达式执行效率的实用技巧。
关键词:Python正则表达式、re模块、字符集、量词、分组捕获、非贪婪匹配、预编译、日志分析、数据清洗
简介:本文系统讲解Python正则表达式的核心语法与实战技巧,涵盖基础字符匹配、量词控制、边界处理等核心概念,详细介绍re模块的match/search/findall等核心方法,通过分组捕获、非贪婪匹配等高级技巧提升处理效率,结合日志分析、密码验证等实战案例演示综合应用,最后提供调试工具与性能优化建议。