Python,正则表达式,在花括号中提取分组电子邮件

3

我想从字符串中提取多个电子邮件地址。我正在使用以下正则表达式:

re.findall(r'[\w\.-]+@[\w\.-]+(?:\.[\w]+)+', text)

它运作良好,但有时相同域名的文本电子邮件名称会用花括号分组:

{annie,bonnie}@gmail.com

我的问题是如何正确解析它并提取出单独的电子邮件地址:
annie@gmail.com, bonnie@gmail.com

我尝试修改正则表达式以考虑括号和逗号,并跟随简单函数,但在这种情况下,我从字符串中得到了很多垃圾。

非常感谢任何帮助。


你可以使用类似于 r'(?:({[^{}]*})|[\w.-]+)(@[\w.-]+(?:\.\w+)+)' 的东西,一旦找到匹配项,就可以检查第1组是否匹配,如果是,则用逗号分隔并构建结果输出。 - Wiktor Stribiżew
3个回答

2

您可以使用

(?:{([^{}]*)}|\b\w[\w.-]*)(@[\w.-]+\.\w+)

请查看正则表达式演示细节:

  • (?:{([^{}]*)}|\b\w[\w.-]*) - 一个非捕获组,匹配:
  • {([^{}]*)} - {,然后是第1个捕获组,捕获任何零个或多个字符(不包括{}),然后是}
  • | - 或者
  • \b\w[\w.-]* - 一个单词边界(它将使匹配更有效),一个单词字符,然后是零个或多个单词、点或连字符字符
  • (@[\w.-]+\.\w+) - 第2个捕获组: 一个@,一个或多个单词、点或连字符字符,然后是.和一个或多个单词字符。

请查看Python演示

import re
text = "Emails like {annie,bonnie}@gmail.com, annie2@gmail.com, then a bonnie2@gmail.com."
emails = []
rx_email = re.compile( r'(?:{([^{}]*)}|\b\w[\w.-]*)(@[\w.-]+\.\w+)' )
for m in rx_email.finditer(text):
    if m.group(1):
        for email in m.group(1).split(','):
            emails.append(f'{email}{m.group(2)}')
    else:
        emails.append(m.group())
print(emails)
# => ['annie@gmail.com', 'bonnie@gmail.com', 'annie2@gmail.com', 'bonnie2@gmail.com']

逻辑如下:
  • 获取邮箱地址中@前面带有 {...} 的邮件,并将大括号内的内容捕获到第一组,将 @... 捕获到第二组。
  • 检查是否匹配了第一组,如果是,则使用逗号分隔内容并构建结果匹配项,通过连接逗号分隔的用户名和域部分来实现。
  • 如果未匹配第一组,则将匹配值附加到结果列表中。

1
你可以使用re.findall和列表推导式一起使用:
inp = "{annie,bonnie}@gmail.com"
parts = re.findall(r'\{(.*?)\}(@\S+)\b', inp)[0]
emails = [email + parts[1] for email in parts[0].split(',')]
print(emails)

这将打印:

['annie@gmail.com', 'bonnie@gmail.com']

r'\{(.*?)\}(@\S+)\b'不再匹配annie@gmail.com - Wiktor Stribiżew
它正在工作,可能只是有点不舒服 - 需要应用两个函数:首先提取所有正常的电子邮件,其次 - 处理所有分组情况。 - Alex_Y
1
@Oleksii 好吧,对于 {...} 这种情况,你需要做很多额外的工作,我看不出有任何绕过它的方法。如果你真的想只进行一次遍历,那么可以考虑使用正则表达式迭代器。你可以匹配任意一种情况,然后决定如何处理每一种情况。 - Tim Biegeleisen

1
x = 'xy2@gmail.com data@gmail.com google@gmail.com {annie,bonnie}@gmail.com'
q = []
for i,j in enumerate(x):
    if '{' == j or '}' ==j :
        q.append(i)  
    
y1 = x[q[0]+1:q[1]]
a1 = y1.replace(','," ")
a1 = a1.split(" ")
z = [i+'@gmail.com' for i in a1]

x = x.replace("{",'')
y = x.replace("}",'')
z1 = " ".join(z)
z2 = y.replace(y1,z1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接