推荐使用带捕获组的正则表达式 r'\b[\w.%+-]+@([a-za-z0-9.-]+.[a-za-z]{2,})\b' 提取邮箱域名,支持连字符、多级子域及常见顶级域名,避免残缺匹配。
直接用带捕获组的正则匹配,提取 @ 后面直到末尾的部分即可,无需额外切分或索引操作。
核心正则模式:用括号捕获域名段
推荐使用:([a-zA-Z0-9.-]+\.[a-zA-Z]{2,}) 作为域名捕获组,配合完整邮箱结构一起匹配。例如:
-
r'[\w.%+-]+@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})'—— 只捕获域名(不含用户名和 @) - 加上单词边界
\b可避免误匹配,如:r'\b[\w.%+-]+@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})\b' - 若需支持多级域名(如 mail.sub.domain.co.uk),把
[a-zA-Z0-9.-]+改为(?:[a-zA-Z0-9-]+\.)+,即:r'\b[\w.%+-]+@((?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{1,6})\b'
Python 中快速提取域名的写法
用 re.findall() 直接获取所有域名:
domains = re.findall(r'\b[\w.%+-]+@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})\b', text)- 结果是纯字符串列表,如
['example.com', 'sub.domain.co.uk'] - 若文本中含多个邮箱,
findall自动返回全部域名;只取第一个可用search+.group(1)
注意边界与常见陷阱
域名提取不准,往往不是正则写错,而是边界没控好:
- 不用
\b容易截出com或domain.co这类残缺片段 -
[a-zA-Z]{2,}要求顶级域名至少两个字母,能排除.c或孤立点号 - 避免用
\w+匹配域名——它会把连字符-和点号.当作单词字符吞掉,导致my-site.com被截成my-site
实际例子验证
输入文本:"联系 admin@my-company.org 或 dev@test.org.cn,另见 help@sub.mail.example.co.uk"
- 匹配结果:
['my-company.org', 'test.org.cn', 'sub.mail.example.co.uk'] - 关键点:最后一项含三级子域,靠
[a-zA-Z0-9.-]+中的点号允许和连字符支持实现识别 - 若用更严格模式(如 RFC 近似),可替换为
(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,},兼容更多合法格式










