🎯 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.cabc, 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() - 预编译模式

掌握正则表达式,你将能够优雅地处理各种文本处理任务。记住:正则表达式是一把双刃剑,适度的正则简洁高效,过度的正则难以维护。在使用时要平衡简洁性与可读性。

参考资料

  1. Python官方文档 - re模块
  2. 正则表达式30分钟入门教程
  3. Regex101在线测试工具

💡 小提示:复杂的正则表达式建议先在 Regex101 等在线工具中测试,确认无误后再写入代码!

posted @ 2026-04-14 22:25  码小小小仙  阅读(60)  评论(0)    收藏  举报