问题: 如何用正则表达式提取字符串中的邮箱地址(简单格式)?

👇 点击展开/折叠 面试背诵模板(建议先背这个) 使用 re.findall() 配合模式 r'\w+@\w+\.\w+' 即可提取字符串中所有简单格式的邮箱地址。\w+ 匹配用户名部分(字母、数字、下划线),@ 为字面量分隔符,\w+ 匹配域名部分,\. 转义匹配点号,\w+ 匹配顶级域名(如 com、cn)。该模式适用于不含特殊字符(如点号、下划线、加号)的基础邮箱格式,匹配失败返回空列表。
---

模式拆解与边界说明

模式片段 含义 对应邮箱部分
\w+ 匹配一次或多次字母、数字、下划线 用户名(如 test)
@ 字面量字符 分隔符
\w+ 匹配一次或多次字母、数字、下划线 域名主体(如 qq)
\. 转义匹配字面量点号 点号分隔符
\w+ 匹配一次或多次字母、数字、下划线 顶级域名(如 com)
1
2
3
4
import re
text = "联系邮箱: test@qq.com 或 admin@163.cn,备用: user@outlook.com"
emails = re.findall(r'\w+@\w+\.\w+', text)
print(emails) # ['test@qq.com', 'admin@163.cn', 'user@outlook.com']

常见匹配陷阱与增强方案

\w 仅匹配字母、数字、下划线,无法匹配含 . 或 - 的邮箱(如 john.doe@company.com 或 user-name@domain.com)。若需支持此类格式,需将 \w+ 替换为 [\w.-]+,允许用户名和域名中包含点号和连字符。

1
2
3
4
# 增强版:支持点号和连字符
pattern = r'[\w.-]+@[\w.-]+\.\w+'
text = "联系: john.doe@company.com, user-name@mail.com"
print(re.findall(pattern, text)) # ['john.doe@company.com', 'user-name@mail.com']

提取多个结果时的 API 选择

  • **re.findall()**:返回字符串列表,适合数据量小、仅需结果的场景。
  • **re.finditer()**:返回 Match 对象迭代器,可同时获取匹配位置(如 span()),适合数据量大或需位置信息的场景。
1
2
for match in re.finditer(r'\w+@\w+\.\w+', text):
print(match.group(), match.span())

区分提取与校验(业务提示)

  • 提取(findall / search):从大段文本中抓取邮箱,容忍周围存在多余字符。
  • 校验(fullmatch):严格验证用户输入的完整字符串是否为合法邮箱,通常使用更复杂的模式或第三方库(如 email-validator),确保无前后缀干扰。