繁体   English   中英

从电子邮件文本中解析“发件人”地址

[英]Parsing “From” addresses from email text

我正在尝试从电子邮件的纯文本脚本中提取电子邮件地址。 我拼凑了一些代码来查找地址本身,但我不知道如何区分它们; 现在它只是吐出文件中的所有电子邮件地址。 我想这样做它只会吐出前面有“From:”和一些通配符的地址,并以“>”结尾(因为电子邮件设置为From [name] <[email]> )。

这是现在的代码:

import re #allows program to use regular expressions
foundemail = []
#this is an empty list

mailsrch = re.compile(r'[\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4}')
 #do not currently know exact meaning of this expression but assuming
 #it means something like "[stuff]@[stuff][stuff1-4 letters]"

        # "line" is a variable is set to a single line read from the file
# ("text.txt"):
for line in open("text.txt"):

    foundemail.extend(mailsrch.findall(line))

    # this extends the previously named list via the "mailsrch" variable
      #which was named before

print foundemail

试试这个:

>>> from email.utils import parseaddr

>>> parseaddr('From: vg@m.com')
('', 'vg@m.com')

>>> parseaddr('From: Van Gale <vg@m.com>')
('Van Gale', 'vg@m.com')

>>> parseaddr('    From: Van Gale <vg@m.com>   ')
('Van Gale', 'vg@m.com')

>>> parseaddr('blah abdf    From: Van Gale <vg@m.com>   and this')
('Van Gale', 'vg@m.com')

不幸的是,它只找到每行中的第一封电子邮件,因为它期待标题行,但也许这没关系?

import email
msg = email.message_from_string(str)

# or
# f = open(file)
# msg = email.message_from_file(f)

msg['from']

# and optionally
from email.utils import parseaddr
addr = parseaddr(msg['from'])

如果您的目标实际上是从文本中提取电子邮件地址,则应使用为此目的而构建的库。 正则表达式不适合匹配任意电子邮件地址。

但是如果你这样做是为了更好地理解正则表达式,我会采用扩展你正在使用的表达式的方法来包含你想要匹配的额外文本。 首先,让我解释一下正则表达式的作用:

[\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4}
  • [\\w\\-]匹配任何“单词”字符(字母,数字或下划线) 连字符
  • [\\w\\-\\.]+匹配(任何单词字符连字符句点)一次或多次
  • @匹配文字'@'
  • [\\w\\-]匹配任何单词字符连字符
  • [\\w\\-\\.]+匹配(任何单词字符连字符句点)一次或多次
  • [a-zA-Z]{1,4}匹配1,2,3或4个小写或大写字母

所以这匹配了一个“单词”的序列,它可能包含连字符或句号,但不以句号开头,后跟@符号,后跟另一个以字母结尾的“单词”(与之前相同的含义)。

现在,为了您的目的修改它,让我们添加正则表达式部分以匹配“From”,名称和尖括号:

From: [\w\s]+?<([\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4})>
  • From:匹配文字文本“From:”
  • [\\w\\s]+? 匹配一个或多个连续的单词字符空格字符。 问号使得匹配非贪婪,因此它将匹配尽可能少的字符,同时仍然允许整个正则表达式匹配(在这种情况下,它可能没有必要,但它确实使匹配更有效,因为事情是之后立即出现不是字符或空格字符)。
  • <匹配文字小于号(开角括号)
  • 您之前使用的正则表达式现在被括号括起来。 这使它成为一个捕获组 ,因此您可以调用m.group(1)来获取与正则表达式部分匹配的文本。
  • >匹配文字大于号

由于正则表达式现在使用捕获组,因此您的代码也需要更改一点:

import re
foundemail = []

mailsrch = re.compile(r'From: [\w\s]+?<([\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4})>')

for line in open("text.txt"):
    foundemail.extend([m.group(1) for m in mailsrch.finditer(line)])

print foundemail

[m.group(1) for m in mailsrch.finditer(line)]的代码[m.group(1) for m in mailsrch.finditer(line)]从正则表达式找到的每个匹配中生成第一个捕获组中的列表(请记住,这是括号中的部分)。

mailsrch = re.compile(r'[\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4}')

表达分解:

[\\w-] :任何单词字符(字母数字,加上下划线)或破折号

[\\w-.]+ :任何单词字符,短划线或句点/点,一次或多次

@ :literal @ symbol

[\\w-][\\w-.]+ :任何单词char或dash,后跟任何单词char,dash或period一次或多次。

[a-zA-Z]{1,4} :任何字母字符1-4次。

要使此匹配仅包含以From:开头的行,并包含在<和>符号中:

import re

foundemail = []
mailsrch = re.compile(r'^From:\s+.*<([\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4})>', re.I | re.M)
foundemail.extend(mailsrch.findall(open('text.txt').read()))

print foundemail

使用电子邮件和邮箱包解析电子邮件的纯文本版本。 这会将其转换为一个对象,该对象将能够提取“发件人”字段中的所有地址。

如果需要处理其他标题字段或消息正文,您还可以对消息进行大量其他分析。

作为一个简单的示例,以下(未经测试的)代码应该读取unix样式邮箱中的所有邮件,并打印所有“from”标头。

import mailbox
import email

mbox = mailbox.PortableUnixMailbox(open(filename, 'rU'), email.message_from_file)

for msg in mbox:
   from = msg['From']
   print from

粗略地说,你可以:

from email.utils import parseaddr

foundemail = []
for line in open("text.txt"):
    if not line.startswith("From:"): continue
    n, e = parseaddr(line)
    foundemail.append(e)
print foundemail

这利用了内置的python parseaddr函数来解析来自行的地址(如其他答案所示),而无需解析整个消息的开销(例如,通过使用功能更全面的电子邮件和邮箱包)。 这里的脚本只是跳过任何不以“From:”开头的行。 开销对您来说是否重要取决于您的输入有多大以及您执行此操作的频率。

如果您可以合理地确定包含这些电子邮件地址的行以空格开头,后跟“From:”,您可以简单地执行此操作:

addresslines = []
for line in open("text.txt"):
    if line.strip().startswith("From:"):
        addresslines.append(line)

然后 - 或者将它们添加到列表中 - 您可以优化地址线项目以准确地给出您想要的内容

“[东东] @ [东东] [stuff1-4字母]”是对的,但如果你想你可以使用我刚刚发现了,一招解码正则表达式在这里 在交互式Python会话中执行compile(),如下所示:

mailsrch = re.compile(r'[\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4}', 128)

它将打印出以下内容:

in 
  category category_word
  literal 45
max_repeat 1 65535 
  in 
    category category_word
    literal 45
    literal 46
literal 64 
in 
  category category_word
  literal 45
max_repeat 1 65535 
  in 
    category category_word
    literal 45
    literal 46
max_repeat 1 4 
  in 
    range (97, 122)
    range (65, 90)

如果您能够习惯它,那么它将向您展示RE的工作原理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM