核心机制与语法
- 元字符:构成模式的基础
-
.:匹配任意字符(换行符除外,除非使用re.DOTALL)*:匹配前一个字符0次或多次(贪婪)+:匹配前一个字符1次或多次(贪婪)?:匹配前一个字符0次或1次;或使*、+变为非贪婪(*?、+?){m,n}:匹配前一个字符m到n次^:匹配字符串开头(或在[]内表示取反)$:匹配字符串结尾|:逻辑或(如cat|dog)
- 字符类
[]:匹配括号内任意一个字符
-
[aeiou]:匹配任意元音[0-9a-fA-F]:匹配十六进制数字[^0-9]:匹配非数字字符(^在开头表示取反)
- 预定义字符集:
-
\d:数字[0-9]\D:非数字[^0-9]\s:空白字符[ \t\n\r\f\v]\S:非空白字符[^ \t\n\r\f\v]\w:单词字符[a-zA-Z0-9_](取决于区域设置和re.ASCII)\W:非单词字符[^a-zA-Z0-9_]
- 分组
()与捕获:
-
- 分组:将多个字符视为一个整体应用量词,如
(ab)+ - 捕获:匹配的子串被存储,可通过
\num(模式内)或.group(num)(匹配对象)引用。使用(?:...)进行非捕获分组。
- 分组:将多个字符视为一个整体应用量词,如
- 贪婪 vs 非贪婪:
-
- 默认量词(
*,+,?,{})是贪婪的,匹配尽可能长的字符串。 - 在量词后加
?使其变为非贪婪(懒惰),匹配尽可能短的字符串(如*?,+?,??,{m, n}?)。
- 默认量词(
Python re 模块核心函数
re.compile(pattern, flags=0):预编译正则表达式为模式对象,提高效率(尤其需多次使用同一模式时)。re.search(pattern, string, flags=0):扫描字符串,返回第一个匹配的Match对象(包含位置、分组信息),无匹配返回None。re.match(pattern, string, flags=0):仅在字符串开头匹配,返回Match对象或None。re.findall(pattern, string, flags=0):返回字符串中所有非重叠匹配的列表。若模式中有分组,返回分组元组列表。re.finditer(pattern, string, flags=0):返回一个迭代器,生成所有非重叠匹配的Match对象。re.sub(pattern, repl, string, count=0, flags=0):将字符串中匹配pattern的子串替换为repl(字符串或函数),返回新字符串。count指定最大替换次数。re.split(pattern, string, maxsplit=0, flags=0):根据模式匹配项分割字符串,返回列表。maxsplit指定最大分割次数。
实用示例代码
import re
# 示例1:提取日志中的时间戳和错误级别
log_line = "2023-10-27 14:30:15 [ERROR] Connection timeout at module X"
pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(\w+)\] (.+)'
match = re.search(pattern, log_line)
if match:
timestamp, level, message = match.groups()
print(f"时间: {timestamp}, 级别: {level}, 信息: {message}") # 输出: 时间: 2023-10-27 14:30:15, 级别: ERROR, 信息: Connection timeout at module X
# 示例2:验证邮箱格式
def validate_email(email):
pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$' # 较简化的示例
return re.match(pattern, email) is not None
print(validate_email("user.name@example.com")) # True
print(validate_email("invalid.email@")) # False
# 示例3:安全提取HTML标签内容 (非贪婪匹配演示)
html_snippet = "<p>First paragraph</p><div>Important content</div>"
pattern = r'<([a-z]+)>(.*?)</\1>' # 使用\1引用第一个分组匹配的标签名,.*? 非贪婪匹配内容
matches = re.findall(pattern, html_snippet)
for tag, content in matches:
print(f"标签: {tag}, 内容: '{content}'") # 输出: 标签: p, 内容: 'First paragraph' / 标签: div, 内容: 'Important content'
# 示例4:使用re.sub进行复杂替换 (日期格式重排)
date_str = "Order date: 27-10-2023, Delivery: 05-11-2023"
new_date_str = re.sub(r'(\d{2})-(\d{2})-(\d{4})', r'\3-\2-\1', date_str) # 将 dd-mm-yyyy 替换为 yyyy-mm-dd
print(new_date_str) # 输出: Order date: 2023-10-27, Delivery: 2023-11-05
避坑指南与高效技巧
- 预编译重用:频繁使用的正则务必用
re.compile。 - 警惕贪婪陷阱:HTML/XML解析优先考虑
.*?非贪婪模式。 - 善用原始字符串:模式字符串前加
r(如r"\d"),避免Python转义干扰。 - 零宽断言:
(?=...)(肯定前瞻)、(?!...)(否定前瞻)、(?<=...)(肯定后顾)、(?<!...)(否定后顾)用于匹配位置而非字符,功能强大。 - 合理使用分组:仅需捕获时用非捕获分组
(?:...)提升效率。 - 利用
re.VERBOSE标志:编写带注释的多行复杂正则表达式,提高可读性。 - 测试与调试:使用在线工具(如regex101.com)测试和调试正则表达式。
掌握Python正则表达式,你将能轻松驯服最桀骜不驯的文本数据,大幅提升开发效率!

被折叠的 条评论
为什么被折叠?



