簡體   English   中英

忽略不完全匹配正則表達式的字符串?

[英]Ignore strings which do not completely match regex?

我想使用正則表達式返回電子郵件的所有收件人。 例如:

Date: Wed, 6 Dec 2000 02:03:00 -0800 (PST)
From: donald.herrick@enron.com
To: brianherrick@email.msn.com, herriceu2@tdprs.state.tx.us, 
    robertherrick@bankunited.com, kristi.demaiolo@enron.com, 
    suresh.raghavan@enron.com, harry.arora@enron.com
Subject: FW: If Santa Answered his mail...
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-From: Donald W Herrick
X-To: brianherrick@email.msn.com, HERRICEU2@tdprs.state.tx.us, RobertHerrick@bankunited.com, Kristi Demaiolo, Suresh Raghavan, Harry Arora
X-cc: 
X-bcc: 

應該返回(從“收件人:”行) brianherrick @ email.msn.com,herriceu2 @ tdprs.state.tx.us,robertherrick @ bankunited.com,kristi.demaiolo @ enron.com,suresh.raghavan @ enron.com ,harry.arora @ enron.com

不是 (來自“ X-To:”行) brianherrick @ email.msn.com,HERRICEU2 @ tdprs.state.tx.us,RobertHerrick @ bankunited.com

我當前的正則表達式是re.findall([To:\\s][\\w\\.-]+@[\\w\\.-]+, text) ,它返回“ To:”,“ X-To:”中的所有內容和“發件人:”行。

我的問題:

  1. 為什么還返回“發件人:”行上的電子郵件地址? 它與正則表達式的[To:\\s]部分不匹配?
  2. 如何確保僅返回“收件人:”之后的電子郵件地址? (也就是說,如何排除“ X-To:”之后的電子郵件地址?我認為您可以為此使用先行斷言,但是我不確定該怎么做?

作為@MartijnPieters答案的附錄,正則表達式可能不是JOB的正確工具。 要解析電子郵件,建議使用email.parser

>>> from email.parser import Parser
>>> headers = Parser().parsestr(email_str)
>>> pprint.pprint(map(str.strip, headers['to'].split()))
['brianherrick@email.msn.com,',
 'herriceu2@tdprs.state.tx.us,',
 'robertherrick@bankunited.com,',
 'kristi.demaiolo@enron.com,',
 'suresh.raghavan@enron.com,',
 'harry.arora@enron.com']

您誤解了角色類的作用; 隨時隨地模式相匹配的字符串包含一個To:或空白字符。

這是因為[To:\\s]一個字符類建模,集合中的任何一個字符都將匹配。 這就是為什么您的From:行匹配; :d之間的空格在這里就足夠了。

如果您需要驗證整個標題名稱,請使用^將匹配項錨定到行的開頭,但刪除該字符類:

r'^To:\s+[\w\.-]+@[\w\.-]+'

現在,如果使用re.MULTILINE標志,則To:部分僅在行的開頭才匹配:

>>> import re
>>> text = '''\
... Date: Wed, 6 Dec 2000 02:03:00 -0800 (PST)
... From: donald.herrick@enron.com
... To: brianherrick@email.msn.com, herriceu2@tdprs.state.tx.us, 
...     robertherrick@bankunited.com, kristi.demaiolo@enron.com, 
...     suresh.raghavan@enron.com, harry.arora@enron.com
... Subject: FW: If Santa Answered his mail...
... Mime-Version: 1.0
... Content-Type: text/plain; charset=us-ascii
... Content-Transfer-Encoding: 7bit
... X-From: Donald W Herrick
... X-To: brianherrick@email.msn.com, HERRICEU2@tdprs.state.tx.us, RobertHerrick@bankunited.com, Kristi Demaiolo, Suresh Raghavan, Harry Arora
... X-cc: 
... X-bcc: 
... '''
>>> re.findall(r'^To:\s+[\w\.-]+@[\w\.-]+', text)
[]
>>> re.findall(r'^To:\s+[\w\.-]+@[\w\.-]+', text, flags=re.M)
['To: brianherrick@email.msn.com']

這只能匹配第一個電子郵件地址,並且不包含全名(例如Brian Herrick <brianherrick@email.msn.com> )。

您必須匹配整個標題

re.findall(r'^To:\s+((?:.*(?:\n[ \t]+)?)*)', text, flags=re.M)

這與To:頭匹配,后跟任意數量的頭連續行(以空格開頭):

>>> re.findall(r'^To:\s+((?:.*(?:\n[ \t]+)?)*)', text, flags=re.M)
['brianherrick@email.msn.com, herriceu2@tdprs.state.tx.us, \n    robertherrick@bankunited.com, kristi.demaiolo@enron.com, \n    suresh.raghavan@enron.com, harry.arora@enron.com']

並且您必須分別提取電子郵件地址。

就我個人而言,我將研究email ,這將使抓取標頭變得更加容易:

import email

message = email.message_from_string(text)
to_headers = message.get_all('to')
addresses = email.utils.getaddresses(to_headers)

演示:

>>> import email
>>> m = email.message_from_string(text)
>>> m.get_all('to')
['brianherrick@email.msn.com, herriceu2@tdprs.state.tx.us, \n    robertherrick@bankunited.com, kristi.demaiolo@enron.com, \n    suresh.raghavan@enron.com, harry.arora@enron.com']
>>> email.utils.getaddresses(m.get_all('to'))
[('', 'brianherrick@email.msn.com'), ('', 'herriceu2@tdprs.state.tx.us'), ('', 'robertherrick@bankunited.com'), ('', 'kristi.demaiolo@enron.com'), ('', 'suresh.raghavan@enron.com'), ('', 'harry.arora@enron.com')]

現在,您擁有了所有的電子郵件地址。

當使用正則表達式時,也可以應用email.utils.getaddresses()函數

>>> email.utils.getaddresses(re.findall(r'^To:\s+((?:.*(?:\n[ \t]+)?)*)', text, flags=re.M))
[('', 'brianherrick@email.msn.com'), ('', 'herriceu2@tdprs.state.tx.us'), ('', 'robertherrick@bankunited.com'), ('', 'kristi.demaiolo@enron.com'), ('', 'suresh.raghavan@enron.com'), ('', 'harry.arora@enron.com')]

regex模塊:無限向后看及其他功能

如果要使用正則表達式,建議您使用出色的regex模塊,而不要使用re 此正則表達式將返回所有匹配項:

(?<=(?<!X\S+)To:\s*(?:[^@\s]+@[^\,\s]+,\s*)*?)[^@\s]+@[^\,\s]+

樣例代碼

我在Python 3.4中對此進行了測試。

import regex
subject = """Date: Wed, 6 Dec 2000 02:03:00 -0800 (PST)
From: donald.herrick@enron.com
To: brianherrick@email.msn.com, herriceu2@tdprs.state.tx.us, 
    robertherrick@bankunited.com, kristi.demaiolo@enron.com, 
    suresh.raghavan@enron.com, harry.arora@enron.com
Subject: FW: If Santa Answered his mail...
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-From: Donald W Herrick
X-To: brianherrick@email.msn.com, HERRICEU2@tdprs.state.tx.us, RobertHerrick@bankunited.com, Kristi Demaiolo, Suresh Raghavan, Harry Arora
X-cc: 
X-bcc: """
pattern = "(?<=(?<!X\S+)To:\s*(?:[^@\s]+@[^\,\s]+,\s*)*?)[^@\s]+@[^\,\s]+"

for match in regex.finditer(pattern, subject):
    print(match.group())

產量

brianherrick@email.msn.com
herriceu2@tdprs.state.tx.us
robertherrick@bankunited.com
kristi.demaiolo@enron.com
suresh.raghavan@enron.com
harry.arora@enron.com

說明

  • 我們后面有一個很大的回望,然后是一個非常基本的電子郵件匹配器: [^@\\s]+@[^\\,\\s]+ ,它匹配不是arrobas或空白字符的任何字符,然后是arrobas,然后是不是逗號或空格字符(輸入中的電子郵件結尾定界符)
  • 如果需要,可以用更復雜的電子郵件正則表達式代替該電子郵件匹配器
  • 現在到后面的大表情``(?<=(?
  • 第一部分(?<!X-)To:\\s*To:匹配,只要不以Xsomething ,就由否定的后向(?<!X-)斷言
  • 非捕獲組(?:[^@\\s]+@[^\\,\\s]+,\\s*)*? 匹配表達式[^@\\s]+@[^\\,\\s]+,\\s*所需的數量( *? )以允許后面的匹配。 這是一個“電子郵件跳過程序”,我們可以在每次匹配時逐漸跳過越來越多的電子郵件
  • [^@\\s]+@[^\\,\\s]+,\\s*只是簡單的電子郵件,后跟一個逗號和可選的空格字符( \\s不僅匹配空格,而且還匹配回車符,制表符等。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM