一、核心语法(只需记这些)
基础元字符
. # 任意字符(除换行)
\d # 数字 [0-9]
\w # 单词字符 [a-zA-Z0-9_]
\s # 空白字符 [空格\t\n\r\f\v]
^ # 字符串开始
$ # 字符串结束
\] # 字符集合 \[abc\] 匹配 a/b/c \[\^\] # 非字符集合 \[\^abc\] 匹配非a/b/c \| # 或运算 #### 量词(控制重复次数) \* # 0次或多次 + # 1次或多次 ? # 0次或1次 {n} # 正好n次 {n,} # 至少n次 {n,m} # n到m次 #### 分组与引用 () # 捕获分组 (?:) # 非捕获分组(不保存匹配) \\1 # 引用第1个分组 #### 特殊字符 \\. # 匹配点号 \\\\ # 匹配反斜杠 ### 二、最常用的6个函数 #### 1. \*\*re.search()\*\* - 找第一个匹配 import re text = "电话: 138-1234-5678" match = re.search(r"\\d{3}-\\d{4}-\\d{4}", text) if match: print(f"找到电话: {match.group()}") # 138-1234-5678 print(f"位置: {match.start()} 到 {match.end()}") #### 2. \*\*re.findall()\*\* - 找所有匹配 text = "价格: $29.99, $49.99, $19.99" prices = re.findall(r"\\$\\d+\\.\\d{2}", text) print(prices) # \['$29.99', '$49.99', '$19.99'
- **re.match()** - 从开头匹配
text = "2023-12-25 圣诞节"
match = re.match(r"\d{4}-\d{2}-\d{2}", text)
match 从字符串开头检查,search 可在任意位置
4. **re.sub()** - 替换文本
替换所有数字为"X"
text = "密码123,验证码456"
result = re.sub(r"\d+", "X", text)
print(result) # 密码X,验证码X
使用函数替换
def mask(match):
num = match.group()
return "*" * len(num)
result = re.sub(r"\d+", mask, text) # 密码***,验证码***
5. **re.split()** - 用正则分割
text = "苹果,香蕉;橘子 西瓜"
result = re.split(r"[,; ]+", text)
print(result) # ['苹果', '香蕉', '橘子', '西瓜']
6. **re.compile()** - 预编译模式(多次使用)
phone_pattern = re.compile(r"\d{3}-\d{4}-\d{4}")
后续直接使用
texts = ["电话: 138-1234-5678", "手机: 139-8765-4321"]
for text in texts:
match = phone_pattern.search(text)
if match:
print(match.group())
三、实用技巧与实例
1. **提取信息**
提取邮箱用户名和域名
email = "user@example.com"
match = re.match(r"(\w+)@(\w+\.\w+)", email)
if match:
username, domain = match.groups()
print(f"用户名: {username}, 域名: {domain}")
2. **贪婪 vs 非贪婪**
text = "<div>内容1</div><div>内容2</div>"
贪婪模式(默认) - 匹配尽可能长的
greedy = re.findall(r"<div>.*</div>", text)
['<div>内容1</div><div>内容2</div>']
非贪婪模式 - 匹配尽可能短的
lazy = re.findall(r"<div>.*?</div>", text)
['<div>内容1</div>', '<div>内容2</div>']
3. **常用验证模式**
邮箱验证
def is_email(email):
pattern = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
return bool(re.match(pattern, email))
手机号验证(中国)
def is_phone(phone):
pattern = r"^1[3-9]\d{9}$"
return bool(re.match(pattern, phone))
URL验证
def is_url(url):
pattern = r"^https?://[^\s/.?#\].\[\^\\s\]\*"
return bool(re.match(pattern, url))
四、实战示例
示例1:提取网页数据
html = '''
<h1>标题</h1>
<p>价格: $19.99</p>
<p>库存: 50个</p>
提取所有标签内容
tags = re.findall(r"<(\w+)>(.*?)</\1>", html)
for tag, content in tags:
print(f"{tag}: {content}")
示例2:数据清洗
text = """
用户1: 订单号#20231225001, 金额: ¥299.00
用户2: 订单号#20231225002, 金额: ¥1599.50
提取订单信息
orders = re.findall(r"订单号#(\d+).*?¥(\d+\.?\d*)", text)
for order_id, amount in orders:
print(f"订单: {order_id}, 金额: {amount}")
示例3:密码强度检查
def check_password(password):
if len(password) < 8:
return "密码太短"
if not re.search(r"[a-z]", password):
return "需要小写字母"
if not re.search(r"[A-Z]", password):
return "需要大写字母"
if not re.search(r"\d", password):
return "需要数字"
if not re.search(r"[!@#$%^&*]", password):
return "需要特殊字符"
return "密码强度足够"
五、常见问题与技巧
- **原始字符串 r"..."**
用原始字符串避免转义问题
path1 = "C:\\Users\\Name" # 需要转义
path2 = r"C:\Users\Name" # 原始字符串,更清晰
- **flags参数**
text = "Hello\nWorld"
re.IGNORECASE 忽略大小写
re.findall(r"hello", text, re.IGNORECASE)
re.MULTILINE 多行模式
re.findall(r"^Hello", text, re.MULTILINE)
re.DOTALL 让 . 匹配换行符
re.findall(r"Hello.*World", text, re.DOTALL)
- **性能建议**
多次使用同一模式,先编译
pattern = re.compile(r"\d+") # 只编译一次
for text in large_list:
result = pattern.findall(text) # 直接使用
六、速查表
| 场景 | 模式 | 说明 |
|------|------|------|
| 整数 | `\d+` | 一个或多个数字 |
| 小数 | `\d+\.\d+` | 包含小数点的数字 |
| 邮箱 | `\w+@\w+\.\w+` | 简单邮箱验证 |
| 手机 | `1[3-9]\d{9}` | 中国手机号 |
| 中文 | `[\u4e00-\u9fa5]+` | 中文字符 |
| 空格 | `\s+` | 一个或多个空白 |
| 单词 | `\b\w+\b` | 整个单词 |
掌握 `search()`、`findall()`、`sub()` 这三个函数和基础元字符是必须的