跳到主要内容

正则表达式

问题

Python 正则表达式怎么用?常用模式和技巧有哪些?

答案

基础用法

import re

# 匹配
result = re.match(r"^\d+", "123abc") # 从头匹配
result = re.search(r"\d+", "abc123") # 任意位置搜索
results = re.findall(r"\d+", "a1b2c3") # 所有匹配:['1', '2', '3']

# 替换
text = re.sub(r"\d+", "X", "a1b2c3") # "aXbXcX"

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

# 预编译(重复使用时性能更好)
pattern = re.compile(r"\b\w+@\w+\.\w+\b")
emails = pattern.findall("联系 alice@example.com 或 bob@test.org")

分组与命名组

# 捕获组
m = re.search(r"(\d{4})-(\d{2})-(\d{2})", "日期: 2026-03-28")
m.group(0) # "2026-03-28"(整体)
m.group(1) # "2026"
m.groups() # ('2026', '03', '28')

# 命名组
m = re.search(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})", "2026-03-28")
m.group("year") # "2026"
m.groupdict() # {'year': '2026', 'month': '03', 'day': '28'}

常用模式

模式正则示例
手机号r"1[3-9]\d{9}"13812345678
邮箱r"\b[\w.+-]+@[\w-]+\.[\w.-]+\b"user@example.com
IP 地址r"\d{1,3}(\.\d{1,3}){3}"192.168.1.1
URLr"https?://[\w\-._~:/?#\[\]@!$&'()*+,;=]+"https://example.com

贪婪 vs 非贪婪

text = "<h1>标题</h1>"

re.findall(r"<.*>", text) # ['<h1>标题</h1>'] — 贪婪,尽可能多匹配
re.findall(r"<.*?>", text) # ['<h1>', '</h1>'] — 非贪婪(加 ?)

常见面试问题

Q1: re.matchre.search 的区别?

答案

  • match:只在字符串开头匹配
  • search:在字符串任意位置搜索第一个匹配
re.match(r"\d+", "abc123")    # None(开头不是数字)
re.search(r"\d+", "abc123") # <Match '123'>

Q2: 如何避免正则表达式性能问题?

答案

  1. 预编译re.compile() 避免重复编译
  2. 避免回溯灾难:不要嵌套量词如 (a+)+
  3. 使用非捕获组(?:...) 不需要捕获时性能更好
  4. 优先用字符串方法:简单操作用 str.startswith()str.replace()

相关链接