簡體   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