Python 正则表达式实战

正则表达式是文本处理的瑞士军刀:提取邮箱、校验手机号、清洗日志。本文从 re 模块核心函数到常用模式,讲清 Python 正则表达式怎么用。

Python 正则表达式配图:蓝色渐变背景上抽象匹配流带形与网格,放大镜覆盖几何图案,扁平科技插画
正则表达式:文本匹配与提取的利器

一、re 模块核心函数

import re

# re.match:从字符串开头匹配
result = re.match(r"hello", "hello world")
print(result.group())  # hello

# re.search:搜索整个字符串,找第一个匹配
result = re.search(r"world", "hello world")
print(result.group())  # world

# re.findall:找所有匹配,返回列表
results = re.findall(r"\d+", "订单 100 件,单价 25 元")
print(results)  # ['100', '25']

# re.sub:替换
text = re.sub(r"\s+", " ", "a   b  c")
print(text)  # a b c

# re.split:分割
parts = re.split(r"[,;]", "a,b;c,d")
print(parts)  # ['a', 'b', 'c', 'd']

二、常用元字符

符号含义例子
.任意字符(除换行)a.c 匹配 abc、a1c
\d数字\d+ 匹配 123
\w字母数字下划线\w+ 匹配 hello_1
\s空白字符\s+ 匹配多个空格
*0 次或多次ab* 匹配 a、ab、abb
+1 次或多次ab+ 匹配 ab、abb
?0 次或 1 次ab? 匹配 a、ab
{n,m}n 到 m 次\d{11} 匹配 11 位手机号

三、分组与捕获

# 提取邮箱用户名和域名
result = re.search(r"(\w+)@(\w+\.\w+)", "user@example.com")
print(result.group(1))  # user
print(result.group(2))  # example.com

# 命名分组
result = re.search(r"(?P\w+)@(?P\w+\.\w+)", "user@example.com")
print(result.group("username"))  # user
print(result.group("domain"))    # example.com

# 替换中引用分组
text = re.sub(r"(\d{4})-(\d{2})-(\d{2})", r"\3/\2/\1", "2026-10-23")
print(text)  # 23/10/2026
原始字符串:正则表达式推荐用 r 前缀的原始字符串写法,避免反斜杠转义混乱。例如 r"\d+" 比 "\\d+" 清晰。

四、常用正则实战

# 提取手机号
text = "联系电话:13812345678"
phone = re.search(r"1[3-9]\d{9}", text)
print(phone.group())  # 13812345678

# 提取 URL
html = '链接'
url = re.search(r'href="(https?://[^"]+)"', html)
print(url.group(1))  # https://example.com

# 校验邮箱
email = "test@example.com"
is_valid = re.match(r"^[\w.+-]+@[\w-]+\.[\w.]+$", email)
print(bool(is_valid))  # True

# 提取 HTML 标签内容
html = "

标题

内容

" titles = re.findall(r"

(.*?)

", html) print(titles) # ['标题']

五、预编译正则

# 多次使用同一个正则时,预编译提升性能
phone_pattern = re.compile(r"1[3-9]\d{9}")

# 复用
texts = ["电话13812345678", "电话13987654321", "无号码"]
for text in texts:
    m = phone_pattern.search(text)
    if m:
        print(m.group())

六、贪婪与非贪婪

# 贪婪匹配:尽可能多匹配
re.findall(r"<.+>", "")  # ['']

# 非贪婪匹配(加 ?):尽可能少匹配
re.findall(r"<.+?>", "")  # ['', '']

# 实战:提取标签内容用非贪婪
html = "

第一段

第二段

" re.findall(r"

(.*?)

", html) # ['第一段', '第二段']

七、总结

正则表达式的核心是 re 模块的五个函数:match、search、findall、sub、split。记住常用元字符(\d \w \s + * ?),用分组捕获需要的内容,用非贪婪(?)避免过度匹配。多次使用时预编译提升性能。正则不是万能的,复杂 HTML 解析还是用 BeautifulSoup。