【问题标题】:Capturing emails with regex in Python在 Python 中使用正则表达式捕获电子邮件
【发布时间】:2017-08-04 04:55:13
【问题描述】:

我将从一个较大的 CSV 文件中收集零散的电子邮件。我现在正在学习正则表达式。我正在尝试从这个例句中提取电子邮件。但是,电子邮件中仅填充了 @ 符号和紧接其前的字母。你能帮我看看怎么回事吗?

import re

String = "'Jessica's email is jessica@gmail.com, and Daniel's email is daniel123@gmail.com. Edward's is edwardfountain@gmail.com, and his grandfather, Oscar's, is odawg@gmail.com.'"

emails = re.findall(r'.[@]', String)
names = re.findall(r'[A-Z][a-z]*',String)

print(emails)
print(names)

【问题讨论】:

    标签: python regex string


    【解决方案1】:

    您的正则表达式电子邮件根本不起作用:emails = re.findall(r'.[@]', String) 匹配 anychar 然后 @

    我会尝试一种不同的方法:匹配句子并提取名称,电子邮件与以下经验假设结合(如果您的文本更改太多,那会破坏逻辑)

    • 所有名称后跟 's"is 某处(使用非贪婪的 .*? 匹配介于两者之间的所有名称
    • \w 匹配任何字母字符(或下划线),只有一个点表示域(否则匹配句子的最后一个点)

    代码:

    import re
    
    String = "'Jessica's email is jessica@gmail.com, and Daniel's email is daniel123@gmail.com. Edward's is edwardfountain@gmail.com, and his grandfather, Oscar's, is odawg@gmail.com.'"
    
    print(re.findall("(\w+)'s.*? is (\w+@\w+\.\w+)",String))
    

    结果:

    [('Jessica', 'jessica@gmail.com'), ('Daniel', 'daniel123@gmail.com'), ('Edward', 'edwardfountain@gmail.com'), ('Oscar', 'odawg@gmail.com')]
    

    转换为 dict 甚至会给你一个字典名称 => 地址:

    {'Oscar': 'odawg@gmail.com', 'Jessica': 'jessica@gmail.com', 'Daniel': 'daniel123@gmail.com', 'Edward': 'edwardfountain@gmail.com'}
    

    一般情况需要更多字符(不确定我是否详尽):

    String = "'Jessica's email is jessica_123@gmail.com, and Daniel's email is daniel-123@gmail.com. Edward's is edward.fountain@gmail.com, and his grandfather, Oscar's, is odawg@gmail.com.'"
    
    print(re.findall("(\w+)'s.*? is ([\w\-.]+@[\w\-.]+\.[\w\-]+)",String))
    

    结果:

    [('Jessica', 'jessica_123@gmail.com'), ('Daniel', 'daniel-123@gmail.com'), ('Edward', 'edward.fountain@gmail.com'), ('Oscar', 'odawg@gmail.com')]
    

    【讨论】:

      【解决方案2】:

      1. 电子邮件

          In [1382]: re.findall(r'\S+@\w+\.\w+', text)
          Out[1382]: 
          ['jessica@gmail.com',
           'daniel123@gmail.com',
           'edwardfountain@gmail.com',
           'odawg@gmail.com']
      

      如何运作:所有电子邮件都是xxx@xxx.xxx。需要注意的是,@ 和单数 . 周围有一堆字符。所以,我们使用\S 来划分任何不是空白的东西。而+则是搜索1个或多个这样的字符。 \w+\.\w+ 只是一种奇特的说法,即搜索一个只有一个 . 的字符串。


      2. 姓名

          In [1375]: re.findall('[A-Z][\S]+(?=\')', text)
          Out[1375]: ['Jessica', 'Daniel', 'Edward', 'Oscar']
      

      工作原理:任何以大写字母开头的单词。 (?=\') 是一个前瞻。如您所见,所有名称都遵循Name's 模式。我们想要撇号之前的所有内容。因此,未捕获的前瞻。


      现在,如果您想通过使用大量正则表达式将姓名与电子邮件一起捕获来将姓名映射到电子邮件,您可以。 Jean-François Fabre's answer 是一个好的开始。但我建议先把基础打好。

      【讨论】:

      • odawg@gmail.com.: 最后一封邮件末尾有一个点,其他的也有逗号:)
      • @Jean-FrançoisFabre Last 24 hours。是的,这是艰难的一天——很难取悦人群。
      • @Jean-FrançoisFabre 老实说,当我需要发泄一下时,我会开始锻炼我的锤子——这实际上经常发生。
      • 470 你在抱怨吗?我承认很多用户不接受答案(或接受最蹩脚/最不赞成的答案是因为他们理解)
      • 我刚刚意识到[\w_] 是多余的,因为\w 包含_
      【解决方案3】:

      您需要找到要匹配的锚点、模式。改进的模式可能是:

      import re
      
      String = "'Jessica's email is jessica@gmail.com, and Daniel's email is 
      daniel123@gmail.com. Edward's is edwardfountain@gmail.com, and his 
      grandfather, Oscar's, is odawg@gmail.com.'"
      
      emails = re.findall(r'[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+', String)
      names = re.findall(r'[A-Z][a-z]*', String)
      
      print(emails) 
      print(names)
      

      \w+ 缺少电子邮件地址中允许的“-”。

      【讨论】:

        【解决方案4】:

        这是因为您没有使用重复运算符。下面的代码使用 + 运算符,这意味着字符/子模式在它可以重复 1 到多次之前。

        s = '''Jessica's email is jessica@gmail.com, and Daniel's email is daniel123@gmail.com. Edward's is edwardfountain@gmail.com, and his grandfather, Oscar's, is odawg@gmail.com.'''
        
        p = r'[a-z0-9]+@[a-z]+\.[a-z]+'
        ans = re.findall(p, s)
        
        print(ans)
        

        【讨论】:

        • 感谢 m8。就像我说我是这个正则表达式的新手。
        猜你喜欢
        • 1970-01-01
        • 2015-01-15
        • 1970-01-01
        • 2018-12-04
        • 2021-06-15
        • 2011-12-28
        • 2012-01-02
        • 2015-12-03
        相关资源
        最近更新 更多