正则表达式解析邮件To头收件人地址匹配失败问题排查
问题分析与解决
原正则的问题
你写的正则r'^.*?<?(?P<to>.*)>?'没法实现需求,核心问题有两个:
<?和>?是可选匹配,正则可以直接忽略<和>,直接进入后续捕获组逻辑。- 捕获组里的
.*是贪婪匹配,会从当前位置一直匹配到字符串末尾,哪怕后面有>也不会停下。
所以第二个地址里,正则直接跳过了<的匹配,让(?P<to>.*)把整个字符串都捕获了,根本没提取<>内部的邮箱地址。
修复后的正则方案
用分支匹配的思路:优先匹配带<>的格式并捕获内部内容;如果没有<>,就捕获整个字符串。
修正后的代码:
import re # 分支匹配:先处理带<>的情况,再处理纯文本情况 re_destinatario = re.compile(r'^.*<(?P<to>[^>]+)>|^(?P<to>.+)$') addresses = [ 'XKYDF/ABC (Caixa Corporativa)', 'Fulano de Tal | Atlantica Beans <fulano.tal@atlanticabeans.com>' ] for address in addresses: m = re_destinatario.search(address) print(m.groups()) print(m.group('to'))
运行结果:
('XKYDF/ABC (Caixa Corporativa)', None) XKYDF/ABC (Caixa Corporativa) (None, 'fulano.tal@atlanticabeans.com') fulano.tal@atlanticabeans.com
正则解释
^.*<(?P<to>[^>]+)>:匹配从开头到<的内容,然后捕获<和>之间非>的所有字符([^>]+避免贪婪匹配越过>)。|^(?P<to>.+)$:如果前面的分支匹配失败(即没有<>),就捕获整个非空字符串。
如果不想出现None的组值,也可以用更简洁的优先级写法:
re_destinatario = re.compile(r'(?:^.*<)?(?P<to>[^>]+)(?:>)?$')
不过分支匹配的写法更直观,也更容易维护。
内容的提问来源于stack exchange,提问作者Clodoaldo Pinto
相关产品推荐
相关产品推荐

