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

# 检查字符串是否以"The"开头
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)  # ['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']

代码解释:

  • 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")

# 输出:
# John is 30 years old
# Jane is 25 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)  # ['<h1>Title</h1><p>Content</p>']

# 非贪婪匹配
non_greedy = re.findall(r'<.*?>', text)
print(non_greedy)  # ['<h1>', '</h1>', '<p>', '</p>']

实用示例

电子邮件验证

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.IGNORECASEre.I忽略大小写
re.MULTILINEre.M多行模式,影响^和$
re.DOTALLre.S使.匹配包括换行符在内的所有字符
re.VERBOSEre.X允许编写更易读的正则表达式
re.ASCIIre.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模块提供了强大的正则表达式功能,是文本处理的利器。掌握正则表达式可以让你:

  1. 高效处理文本:快速完成复杂的文本匹配和替换
  2. 数据验证:验证用户输入的格式
  3. 数据提取:从非结构化文本中提取结构化信息
  4. 文本清洗:预处理文本数据用于分析

学习建议

  1. 从简单模式开始,逐步增加复杂度
  2. 使用在线测试工具(如regex101.com)验证你的模式
  3. 为复杂模式添加注释(使用re.VERBOSE
  4. 记住"有些人在遇到问题时会想:‘我知道,我会用正则表达式’。现在他们有两个问题了"

进一步学习

  • 官方文档:https://docs.python.org/3/library/re.html
  • 正则表达式可视化工具:https://regexper.com/
  • 交互式学习:https://regexone.com/

更多推荐