【问题标题】:Extract and count domains address mails from e-mails从电子邮件中提取和统计域地址邮件
【发布时间】:2018-07-06 12:51:20
【问题描述】:

我有一个电子邮件列表,想只提取域并计算每个域出现的次数:

电子邮件:

best@yahoo.com

hello@gmail.com

everybody@gmail.com

再见@gmail.com

day@yahoo.com

table.blue@gmail.com

life@yahoo.com

脚本:

import re
from collections import Counter

with open("mails.txt", "r") as f:
    texte = f.read().split('\n')

    for line in texte:
        newline = re.search("@[\w.]+", line)
        newmail = newline.group()

        mails_value = Counter(newmail).most_common()

        print (mails_value)

输出:

[('@', 1), ('g', 1), ('6', 1), ('5', 1), ('.', 1), ('f', 1 ), ('r', 1)]

Traceback(最近一次调用最后一次):

文件“counting.py”,第 10 行,在

newmail = newline.group()

AttributeError: 'NoneType' 对象没有属性 'group'

良好的输出:

@yahoo.com 3

@gmail.com 4

【问题讨论】:

  • 你不计算提取的提及,先收集,然后找到最常见的,见ideone.com/PyxjGt

标签: python regex counter


【解决方案1】:

您已经很接近了 - 无需将文件拆分为行,只需使用 re.findallre.MULTILINE 和模式 @(.*)$

import re
import collections

with open("mails.txt") as f:
    text = f.read()
domains = re.findall(r'@(.*)$', text, re.MULTILINE)
mails_value = collections.Counter(domains) 
# outputs with example: Counter({'gmail.com': 4, 'yahoo.com': 3})

【讨论】:

    【解决方案2】:

    您不需要正则表达式。如果您可以相信所有输入都是格式正确的电子邮件,那么这就足够了:

    from collections import defaultdict
    
    domain_count = defaultdict(lambda: 0)
    
    with open("mails.txt", "r") as f:
        texte = f.readlines()
    
        for line in texte:
            domain = line.split('@')[-1]
            domain_count[domain] += 1
    
    print (domain_count)
    

    【讨论】:

    • defaultdict(lambda: 0) 可以写成defaultdict(int)。 OP 中使用的Counter 无论如何都更适合这项任务。
    【解决方案3】:

    正则表达式将使您免于创建不必要的列表。

    import re
    from collections import Counter
    
    with open("mails.txt", "r") as f:
        texte = f.read().split('\n')
        l=[]
        for line in texte:
            p=re.compile("(?<=@)[^.]+(?=\.)")
            newline = p.search(line)
            if(newline):
    
                newmail = newline.group(0)
                l.append(newmail)
    
    Counter(l)
    

    输出

    Counter({'gmail': 4, 'yahoo': 3})
    

    【讨论】:

      【解决方案4】:

      你可以使用拆分

      texte = "life@yahoo.com"
      texte.split("@")
      ['life', 'yahoo.com']
      

      【讨论】:

        【解决方案5】:

        进行 2 次拆分。第二个带有@.. 然后附加最后一项并将计数器应用于列表

        import re
        from collections import Counter
        
        with open("mails.txt", "r") as f:
            texte = f.read().split('\n')
        
            domains = []
        
            for line in texte:
                line = line.split('@')
                if line[-1] != "":
                    domains.append(line[-1])
        
        mails_value = Counter(domains).most_common()
        
        print(mails_value)   
        

        [('gmail.com', 4), ('yahoo.com', 3)]

        【讨论】:

          【解决方案6】:
          import re
          from collections import Counter
          
          mails = []
          
          with open("mails.txt", "r") as f:
              texte = f.read().split()
              for i in texte:
                  mails.append(re.search("@[\w.]+", i).group())
          
          mails_value = Counter(mails).most_common()
          print mails_value
          

          【讨论】:

          • [\w.]. 相同
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-05-26
          • 2020-01-17
          • 1970-01-01
          • 1970-01-01
          • 2016-04-12
          • 1970-01-01
          • 2011-12-17
          相关资源
          最近更新 更多