Python re模块:正则表达式完全指南
什么是正则表达式?
正则表达式(Regular Expression,简称regex)是一种强大的文本处理工具,使用特定模式来匹配、查找、替换或分割字符串。Python通过内置的re模块提供正则表达式支持。
为什么使用正则表达式?
| 优势 | 说明 |
|---|
| 强大灵活 | 可以表达复杂的文本匹配规则 |
| 高效简洁 | 用简短模式替代大量普通代码 |
| 标准化 | 多种编程语言支持相似语法 |
| 文本处理 | 解决字符串操作中的复杂问题 |
re模块基础
常用函数概览
| 函数 | 描述 | 基本语法 |
|---|
re.match() | 从字符串起始位置匹配 | re.match(pattern, string) |
re.search() | 扫描整个字符串查找匹配 | re.search(pattern, string) |
re.findall() | 查找所有匹配的子串 | re.findall(pattern, string) |
re.finditer() | 返回匹配项的迭代器 | re.finditer(pattern, string) |
re.sub() | 替换匹配的子串 | re.sub(pattern, repl, string) |
re.split() | 根据模式分割字符串 | re.split(pattern, string) |
基本匹配示例
import re
result = re.match(r'The', 'The quick brown fox')
print(result.group()) if result else print("No match")
result = re.search(r'\d+', 'Order 12345')
print(result.group()) if result else print("No numbers found")
letters = re.findall(r'[a-z]', 'Hello World')
print(letters)
代码解释:
r'' 表示原始字符串,避免转义字符问题match() 只检查字符串开头search() 查找整个字符串中的第一个匹配findall() 返回所有非重叠匹配的列表
正则表达式语法
元字符表
| 元字符 | 描述 | 示例 |
|---|
. | 匹配任意字符(除换行符) | a.c 匹配 “abc”、“a c” |
^ | 匹配字符串开头 | ^The 匹配 "The"开头的字符串 |
$ | 匹配字符串结尾 | end$ 匹配以"end"结尾的字符串 |
* | 前一个字符0次或多次 | bo*k 匹配 “bk”、“bok”、“book” |
+ | 前一个字符1次或多次 | a+b 匹配 “ab”、“aab” |
? | 前一个字符0次或1次 | colou?r 匹配 “color"和"colour” |
{m,n} | 前一个字符m到n次 | a{2,4} 匹配 “aa”、“aaa”、“aaaa” |
[] | 字符集,匹配其中任意一个 | [aeiou] 匹配任何元音字母 |
| | 或操作 | cat|dog 匹配 “cat"或"dog” |
() | 分组和捕获 | (abc)+ 匹配 “abc”、"abcabc"等 |
特殊序列
| 序列 | 描述 | 等价字符集 |
|---|
\d | 任意数字 | [0-9] |
\D | 任意非数字 | [^0-9] |
\s | 任意空白字符 | [ \t\n\r\f\v] |
\S | 任意非空白字符 | [^ \t\n\r\f\v] |
\w | 任意字母数字字符 | [a-zA-Z0-9_] |
\W | 任意非字母数字字符 | [^a-zA-Z0-9_] |
\b | 单词边界 | - |
\B | 非单词边界 | - |
高级功能
分组和捕获
import re
text = "John: 30, Jane: 25"
pattern = r'(\w+): (\d+)'
matches = re.findall(pattern, text)
for name, age in matches:
print(f"{name} is {age} years old")
代码解释:
(\w+) 捕获一个或多个字母数字字符作为组(\d+) 捕获一个或多个数字作为组findall() 返回包含所有匹配组的元组列表
非捕获组和命名组
| 语法 | 描述 | 示例 |
|---|
(?:...) | 非捕获组 | (?:abc) |
(?P<name>...) | 命名捕获组 | (?P<year>\d{4}) |
(?P=name) | 引用命名组 | (?P<word>\w+) (?P=word) |
text = "2023-05-15"
pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
match = re.search(pattern, text)
if match:
print(f"Year: {match.group('year')}")
print(f"Month: {match.group('month')}")
print(f"Day: {match.group('day')}")
贪婪与非贪婪匹配
| 模式 | 类型 | 行为 |
|---|
.* | 贪婪 | 匹配尽可能多的字符 |
.*? | 非贪婪 | 匹配尽可能少的字符 |
text = "<h1>Title</h1><p>Content</p>"
greedy = re.findall(r'<.*>', text)
print(greedy)
non_greedy = re.findall(r'<.*?>', text)
print(non_greedy)
实用示例
电子邮件验证
import re
def validate_email(email):
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.fullmatch(pattern, email))
emails = ["user@example.com", "invalid.email", "another.user@domain.co.uk"]
for email in emails:
print(f"{email}: {'Valid' if validate_email(email) else 'Invalid'}")
URL提取
import re
text = "Visit https://www.example.com or http://sub.domain.org/path"
pattern = r'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+[/\w .-]*'
urls = re.findall(pattern, text)
print("Found URLs:", urls)
电话号码格式化
import re
def format_phone_number(phone):
pattern = r'^(\d{3})(\d{3})(\d{4})$'
return re.sub(pattern, r'(\1) \2-\3', phone)
numbers = ["1234567890", "5551234567"]
for num in numbers:
print(f"Original: {num}, Formatted: {format_phone_number(num)}")
性能优化
编译正则表达式
import re
phone_pattern = re.compile(r'^(\d{3})-(\d{3})-(\d{4})$')
numbers = ["123-456-7890", "555-123-4567"]
for num in numbers:
match = phone_pattern.match(num)
if match:
print(f"Area code: {match.group(1)}")
代码解释:
re.compile() 预编译正则表达式- 编译后的模式可重复使用,提高性能
- 特别适用于大量文本处理或循环中使用的模式
常见陷阱与最佳实践
| 陷阱 | 解决方案 |
|---|
| 过度使用正则表达式 | 简单字符串操作优先 |
| 复杂的难以维护的模式 | 分解为多个简单模式 |
| 贪婪匹配导致意外结果 | 使用非贪婪量词 |
| 忽略大小写敏感性 | 使用re.IGNORECASE标志 |
| 多行匹配问题 | 使用re.MULTILINE标志 |
标志(Flags)
| 标志 | 简写 | 描述 |
|---|
re.IGNORECASE | re.I | 忽略大小写 |
re.MULTILINE | re.M | 多行模式,影响^和$ |
re.DOTALL | re.S | 使.匹配包括换行符在内的所有字符 |
re.VERBOSE | re.X | 允许编写更易读的正则表达式 |
re.ASCII | re.A | 使\w, \W, \b, \B等只匹配ASCII字符 |
pattern = r"""
^ # 字符串开始
[a-z0-9._%+-]+ # 用户名
@ # @符号
[a-z0-9.-]+ # 域名
\. # 点
[a-z]{2,} # 顶级域名
$ # 字符串结束
"""
regex = re.compile(pattern, re.VERBOSE | re.IGNORECASE)
总结
Python的re模块提供了强大的正则表达式功能,是文本处理的利器。掌握正则表达式可以让你:
- 高效处理文本:快速完成复杂的文本匹配和替换
- 数据验证:验证用户输入的格式
- 数据提取:从非结构化文本中提取结构化信息
- 文本清洗:预处理文本数据用于分析
学习建议
- 从简单模式开始,逐步增加复杂度
- 使用在线测试工具(如regex101.com)验证你的模式
- 为复杂模式添加注释(使用
re.VERBOSE) - 记住"有些人在遇到问题时会想:‘我知道,我会用正则表达式’。现在他们有两个问题了"
进一步学习
- 官方文档:https://docs.python.org/3/library/re.html
- 正则表达式可视化工具:https://regexper.com/
- 交互式学习:https://regexone.com/
所有评论(0)