Python3 正则表达式(深入浅出)

Python3 正则表达式:从入门到实战

在处理文本数据时,你是否遇到过这样的场景?需要从一段长文本中提取邮箱、手机号、日期,或者验证用户输入是否符合规范?这些任务如果用传统字符串方法一个个判断,代码会越来越臃肿,维护成本极高。这时候,Python3 正则表达式就是你最有力的工具。

正则表达式(Regular Expression,简称 regex)是一种强大的文本匹配模式语言,它用简洁的语法描述复杂的字符串规则。虽然初看有些抽象,但只要掌握核心概念,你会发现它像一把万能钥匙,能轻松打开各种文本处理的大门。

本文将带你从零开始理解 Python3 正则表达式 的基本语法,通过大量实战案例,掌握常用匹配技巧,并学会如何在真实项目中高效应用。


什么是正则表达式?它为什么重要?

想象你正在整理一份学生名单,里面有姓名、学号、联系电话和邮箱。你想快速筛选出所有手机号码。如果用普通字符串方法,你得写一堆 if 判断,比如检查是否以 1 开头、长度是否为 11 位、是否全是数字……效率低,还容易出错。

而正则表达式可以一句话完成:^1[3-9]\d{9}$。这串字符就是匹配中国大陆手机号的正则模式。

Python3 正则表达式 通过 re 模块提供支持。它的核心优势在于:

  • 语法简洁,表达力强
  • 匹配效率高,尤其适合大规模文本处理
  • 支持提取、替换、分割等复合操作

掌握它,意味着你拥有了处理文本数据的“高级武器”。


基础语法:元字符与字符类

在开始编写正则表达式之前,先认识几个基础元字符。它们就像正则的“关键字”,赋予表达式特殊含义。

元字符 作用 示例
. 匹配任意一个字符(换行符除外) a.c 匹配 "abc"、"a2c"
^ 匹配字符串开头 ^Hello 仅匹配以 "Hello" 开头的字符串
$ 匹配字符串结尾 world$ 仅匹配以 "world" 结尾的字符串
* 前一个字符出现 0 次或多次 a* 匹配 ""、"a"、"aa"
+ 前一个字符出现 1 次或多次 a+ 匹配 "a"、"aa",但不匹配 ""
? 前一个字符出现 0 次或 1 次 a? 匹配 "" 或 "a"
[] 字符类,匹配其中任意一个字符 [abc] 匹配 "a"、"b" 或 "c"
import re

text = "cat, bat, rat"
pattern = r'.at'  # . 代表任意一个字符
matches = re.findall(pattern, text)
print(matches)  # 输出: ['cat', 'bat', 'rat'],每个都由一个字符+at组成

text = "Python is great. I love Python."
pattern = r'^Python'  # ^ 表示开头
result = re.search(pattern, text)
print(result.group() if result else "未匹配")  # 输出: Python

text = "The file is saved."
pattern = r'saved.$'  # $ 表示结尾
result = re.search(pattern, text)
print(result.group() if result else "未匹配")  # 输出: saved.

注意:在 Python 中,推荐使用原始字符串(前缀 r)来定义正则表达式,避免反斜杠被转义。


字符类与量词:构建更精确的匹配规则

光靠单个字符还不够。我们常常需要匹配“数字”、“字母”或“特定范围”。这时,字符类和量词就派上用场了。

常见字符类缩写

缩写 代表含义 示例
\d 数字(0-9) \d{3} 匹配三个数字
\D 非数字 \D+ 匹配一个或多个非数字
\w 字母、数字、下划线 \w+ 匹配单词
\W 非字母、非数字、非下划线 \W+ 匹配标点符号
\s 空白字符(空格、制表符、换行) \s+ 匹配多个空白
\S 非空白字符 \S+ 匹配非空白内容
import re

text = "电话: 138-1234-5678,邮箱: user@example.com"

phone_pattern = r'\d{3}-\d{4}-\d{4}'  # 匹配 123-4567-8901 格式
phone_matches = re.findall(phone_pattern, text)
print("手机号:", phone_matches)  # 输出: ['138-1234-5678']

email_pattern = r'\w+@\w+\.\w+'  # \w+@任意字符@任意字符.任意字符
email_matches = re.findall(email_pattern, text)
print("邮箱:", email_matches)  # 输出: ['user@example.com']

量词 n{m} 表示前面的字符重复 m 次。{m,n} 表示至少 m 次,最多 n 次。{m,} 表示至少 m 次。


分组与捕获:提取关键信息

在实际开发中,我们不仅需要判断是否匹配,更常需要提取匹配内容。这时,分组(())就非常有用。

分组可以将正则表达式的一部分封装起来,后续可以通过 group() 方法提取。

import re

order_text = "订单号:2024-03-15,金额:¥89.50"

date_pattern = r'(\d{4})-(\d{2})-(\d{2})'

match = re.search(date_pattern, order_text)
if match:
    year = match.group(1)   # 第一个分组:年
    month = match.group(2)  # 第二个分组:月
    day = match.group(3)    # 第三个分组:日
    print(f"日期:{year}年{month}月{day}日")  # 输出: 日期:2024年03月15日
else:
    print("未找到日期")

group(0) 是完整匹配结果,group(1) 是第一个括号内的内容,以此类推。


常用函数:findall、search、match、sub、split

Python3 正则表达式 提供了多个实用函数,掌握它们能极大提升开发效率。

函数 作用 适用场景
re.findall() 返回所有匹配项的列表 提取所有符合规则的内容
re.search() 返回第一个匹配对象 判断是否存在匹配
re.match() 从字符串开头匹配 要求完全从头开始匹配
re.sub() 替换匹配内容 文本清洗、格式转换
re.split() 按正则分割字符串 分割复杂分隔符
import re

text = "iPhone 15 Pro, iPhone 14, iPad Air, MacBook Pro"

iphones = re.findall(r'iPhone \d+', text)
print("iPhone 型号:", iphones)  # 输出: ['iPhone 15 Pro', 'iPhone 14']

cleaned = re.sub(r'\d+', '[数字]', text)
print("替换后:", cleaned)  # 输出: iPhone [数字] Pro, iPhone [数字], iPad Air, MacBook Pro

parts = re.split(r'[,\s]+', text)
print("分割结果:", parts)  # 输出: ['iPhone 15 Pro', 'iPhone 14', 'iPad Air', 'MacBook Pro']

re.match()re.search() 的区别:match() 只从开头匹配,而 search() 会在整个字符串中查找。


实战案例:用户输入验证

下面是一个完整的用户注册表单验证场景,展示如何使用 Python3 正则表达式 实现安全输入校验。

import re

def validate_user_input(username, email, phone):
    """
    验证用户输入的用户名、邮箱、手机号
    """
    # 用户名:3-20位字母、数字、下划线,不能以数字开头
    username_pattern = r'^[a-zA-Z][a-zA-Z0-9_]{2,19}$'
    if not re.match(username_pattern, username):
        return False, "用户名格式错误:需以字母开头,长度3-20位"

    # 邮箱:基本格式校验
    email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    if not re.match(email_pattern, email):
        return False, "邮箱格式错误"

    # 手机号:中国大陆11位数字,以1开头
    phone_pattern = r'^1[3-9]\d{9}$'
    if not re.match(phone_pattern, phone):
        return False, "手机号格式错误"

    return True, "验证通过"

test_cases = [
    ("alice123", "alice@example.com", "13812345678"),
    ("123user", "invalid-email", "12345678901"),
]

for user, mail, phone in test_cases:
    valid, msg = validate_user_input(user, mail, phone)
    print(f"用户: {user}, 邮箱: {mail}, 手机: {phone}")
    print(f"结果: {'✓' if valid else '✗'} {msg}\n")

输出结果:

用户: alice123, 邮箱: alice@example.com, 手机: 13812345678
结果: ✓ 验证通过

用户: 123user, 邮箱: invalid-email, 手机: 12345678901
结果: ✗ 用户名格式错误:需以字母开头,长度3-20位

这个例子展示了 Python3 正则表达式 在真实项目中的强大作用:它让复杂的验证逻辑变得简洁、可读、可维护。


小结与建议

Python3 正则表达式 不是“高级技巧”,而是现代开发中不可或缺的基础能力。它能帮助你快速处理日志、清洗数据、验证输入、提取信息,显著提升开发效率。

学习建议:

  • 从简单模式开始,如 \d+\w+
  • 多练习 findallsub,它们最常用
  • 遇到复杂需求时,先分步构建正则表达式
  • 使用在线工具(如 regex101.com)测试和调试表达式
  • 注意转义字符,避免匹配失败

掌握 Python3 正则表达式,就像学会了一种“文本编程语言”。它不会立刻改变你的代码风格,但会在你处理文本时,让你每一次操作都更优雅、更高效。

当你下次面对一段混乱的文本时,不妨想一想:用正则表达式,能不能一句话搞定?答案,往往就在那条简洁的模式中。