私は、「ソフトニューライン」シーケンス(等号、キャリッジリターン、ニューライン)で終わる75の文字列で構成される多くの引用された印刷可能な添付ファイルを含む巨大なmboxファイル(8.8GB)を持っています。
特定の正規表現のすべてのアイテムのmboxコンテンツを検索したいと思います。ただし、特定の一致は複数行に分割できるため、正規表現検索を実行する前に各ソフトニューラインシーケンスを削除する必要があります。
これを行うための最良の方法を見つけるのが難しいです。私が見つけたGNU sedソリューションここsedにファイル全体を1行として処理するように指示するため、失敗します。行の長さが長いため、INT_MAX
sedはエラーメッセージで終了します。私も見ましたが、解決方法がありました。ここリップグレップを使用してください。しかし、これは実際に行をリンクしません。等号は削除されますが、等号のある行はまだ次の行から分離されています。
答え1
最後に説明するのは、mboxを電子メールコンテンツに解析してから(添付ファイルの数を数えている)、そのコンテンツを表示することです。正しいこと!
こうしてください。実際にmboxファイルをメッセージに解析すると、少し気分が良くなります。ここに私の頭の上があります。テストされていませんが、エディタコードでは赤ではありません。
#!/usr/bin/env python3
import mailbox
import re as regex
pattern = regex.compile("BRIANSREGEX")
mb = mailbox.mbox("Briansmails.mbox", create=False)
for msg in mb:
print(f"{msg['Subject']}")
for part in msg.walk():
print(f"| {part.get_content_type()}, {part.get_content_charset()}")
print("-"*120)
payload = part.get_payload(decode=True)
charset = part.get_content_charset
if type(payload) is bytes:
content = ""
try:
content = payload.decode(charset)
except:
# print("failed to decode")
try:
content = payload.decode() # try ascii
match = pattern.search(content)
# do what you want with that match…
if match:
print(f"| matched at {match.start()}")
print("-"*120)
答え2
私はMarcus Müllerの答えに親指を立てましたが、これは彼の答えに基づいたバージョンです。
#!/usr/bin/env python3
import mailbox
import re
import sys
byte_pattern = re.compile(b"https?://[^/]*imgur.com/[a-zA-Z0-9/.]*")
str_pattern = re.compile("https?://[^/]*imgur.com/[a-zA-Z0-9/.]*")
mb = mailbox.mbox(sys.argv[1], create=False)
for msg in mb:
for part in msg.walk():
if part.is_multipart():
continue
payload = part.get_payload(decode=True)
if type(payload) is bytes:
# first, search it as a binary string
for match in byte_pattern.findall(payload):
print(match.decode('ascii'))
# then, try to decode it in case it's utf-16 or something weird
charset = part.get_content_charset()
if charset and charset != 'utf-8':
try:
content = payload.decode(charset)
for match in str_pattern.findall(content):
print(match)
except:
pass
else:
print('failed to get message part as bytes')
リーフではなくノードを含む深さ優先ナビゲーションを実行するため、part
ツリーのリーフノードではなくマルチパートメッセージになる可能性があります。walk
リーフノードの場合のみ、最初にパターンをバイト文字列として取得し、指定された文字セット(UTF-8以外の場合)を使用してテキストにデコードしようとします。 (最も多く使用されているUTF-8の場合、すでにバイト列で検索されています。)