re.findall在Python中使用分组进行正则表达式失败

时间:2012-03-17 07:49:03

标签: python regex

我正在使用正则表达式编写一个python程序来查找电子邮件地址。每当我尝试使用圆括号进行分组时,re.findall函数会给出错误的输出。任何人都可以指出错误/提出替代解决方案吗?

以下是两段代码解释 -

pat = "[\w]+[ ]*@[ ]*[\w]+.[\w]+"
re.findall(pat, 'abc@cs.stansoft.edu.com .rtrt.. myacc@gmail.com ')

给出输出

['abc@cs.stansoft', 'myacc@gmail.com']

但是,如果我在此正则表达式中使用分组并将代码修改为

pat = "[\w]+[ ]*@[ ]*[\w]+(.[\w]+)*"
re.findall(pat, 'abc@cs.stansoft.edu.com .rtrt.. myacc@gmail.com ')

输出

['.com', '.com']

为了确认正则表达式的正确性,我在http://regexpal.com/中使用相同的输入字符串尝试了这个特定的正则表达式(在第二个示例中),并且两个电子邮件地址都成功匹配。

2 个答案:

答案 0 :(得分:3)

在Python中,re.findall仅在没有组时返回整个匹配项,如果有组,则返回组。要解决此问题,您应该使用非捕获组(?:...)。在这种情况下:

pat = "[\w.]+ *@ *\w+(?:\.\w+)*"
re.findall(pat, 'abc@cs.stansoft.edu.com .rtrt.. myacc@gmail.com ')

答案 1 :(得分:1)

如果您想要将用户与主机分开,您可以使用群组:
(连字符是可选的,有些电子邮件有连字符。)

pat = '([\w\.-]+)@([\w\.-]+)'
re.findall(pat, 'abc@cs.stansoft.edu.com .rtrt.. myacc@gmail.com ')

输出:

[('abc', 'cs.stansoft.edu.com'), ('myacc', 'gmail.com')]

为了进一步说明我们可以替换主机,并让用户远离第1组(\ 1):

emails = 'abc@cs.stansoft.edu.com .rtrt.. myacc@gmail.com '
pat = '([\w\.-]+)@([\w\.-]+)'
re.sub(pat, r'\1@live.com', emails)

输出:

'abc@live.com .rtrt.. myacc@live.com '

只需从模式中删除括号即可匹配整个电子邮件:

pat = '[\w\.-]+@[\w\.-]+'
re.findall(pat, 'abc@cs.stansoft.edu.com .rtrt.. myacc@gmail.com ')

输出:

['abc@cs.stansoft.edu.com', 'myacc@gmail.com']