我正在使用正则表达式编写一个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/中使用相同的输入字符串尝试了这个特定的正则表达式(在第二个示例中),并且两个电子邮件地址都成功匹配。
答案 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']