Python: чтение текстов только после определенного шаблона - PullRequest
0 голосов
/ 11 октября 2019

У меня есть pdf сообщения электронной почты, как показано ниже

Jerrmy Bret <jeremy.brett@mnop.com>
To: Jonathan Small <j.small@xyz.com>

FYI...

From: Keven Koster <keve.koster@mnop.com>
To: Jerrmy Bret <jeremy.brett@mnop.com>
Date: 21 Sep 2019
Subject: Approval Required for Travel

Can't Approve as Ruth's approval is required

Цель: я хочу прочитать текст письма, т.е. Can't Approve as Ruth's approval is required.

Мой подход Пока:

Я использую регулярное выражение. Но сначала весь PDF-файл преобразуется в текст. Пост, что я конвертирую их в список.

txt = pdf_to_text(email) # let's assume there is a function that does the conversion jobs. 
txt = txt.split('\n')
pat = re.compile(r'appro.*\,re.I)
extract_txt = [f for f in txt if pat.search(f)]

Приведенный выше код создает список следующим образом:

['Approval', 'Approve','approval']

Мне нужно запустить регулярное выражение только в теле письма, а не в теме.

Несколько предположений:

  1. В теле письма должно содержаться слово «Одобрить»
  2. В строке темы может содержаться или не содержаться слово «Утвердить»

Как я могу решить эту проблему? Один из способов убедиться, что я забираю только содержимое почты, - это применить регулярное выражение после subject line. Любая подсказка?

PS Я не могу использовать любую почтовую библиотеку Python, такую ​​как IMAPlib.

Ответы [ 3 ]

0 голосов
/ 11 октября 2019

Использование парсера сделает вашу жизнь проще.

В дальнейшем я использую регулярное выражение только для разделения блока нескольких писем, правило: "дваперевод строки с последующим заголовком ". Это работает достаточно хорошо, когда отдельные сообщения разделены пустой строкой. Не стесняйтесь использовать выражение, которое лучше соответствует вашим входным данным.

import re
import email

# what your text conversion function produces ...
source_text = '''From: Jerrmy Bret <jeremy.brett@mnop.com>
To: Jonathan Small <j.small@xyz.com>

FYI...

From: Keven Koster <keve.koster@mnop.com>
To: Jerrmy Bret <jeremy.brett@mnop.com>
Date: 21 Sep 2019
Subject: Approval Required for Travel

Can't Approve as Ruth's approval is required
'''

for raw_mail in re.split(r'\n\n(?=\w+: )', source_text):
    mail = email.message_from_string(raw_mail)
    body = mail.get_payload()

    if 'approve' in body.lower():
        print('match in email body')
        # ...

    if 'Subject' in mail and 'approve' in mail['Subject']:
        print('match in email subject')
        # ...

При необходимости в вашем случае прочитайте , как обращаться с составными сообщениями .

0 голосов
/ 11 октября 2019

Если не имеет значения, находится ли Approve / Approved / Approval в теме или теле письма, вы можете сделать это:

import re

text = '''From: Jerrmy Bret <jeremy.brett@mnop.com>
To: Jonathan Small <j.small@xyz.com>
Date: 21 Sep 2019
Subject: Stuff

FYI...

From: Keven Koster <keve.koster@mnop.com>
To: Jerrmy Bret <jeremy.brett@mnop.com>
Date: 21 Sep 2019
Subject: Approval Required for Travel

Can't Approve as Ruth's approval is required

From: Jerrmy Bret <jeremy.brett@mnop.com>
To: Keven Koster <keve.koster@mnop.com>
Date: 21 Sep 2019
Subject: Approval Required for Travel

ok thanks Keven, will talk to Ruth
'''

email_regex = re.compile(
    r'(From:(?:(?!From:).)+)',
    re.DOTALL|re.MULTILINE
)
approval_regex = re.compile(
    r'approv(?:e|ed|al)',
    re.IGNORECASE
)
approved_emails = [
   email for email in email_regex.findall(text)
   if approval_regex.search(email)
]
print(approved_emails)

# output
[
   "From: Keven Koster <keve.koster@mnop.com>\nTo: Jerrmy Bret <jeremy.brett@mnop.com>\nDate: 21 Sep 2019\nSubject: Approval Required for Travel\n\nCan't Approve as Ruth's approval is required\n\n",
   'From: Jerrmy Bret <jeremy.brett@mnop.com>\nTo: Keven Koster <keve.koster@mnop.com>\nDate: 21 Sep 2019\nSubject: Approval Required for Travel\n\nok thanks Keven, will talk to Ruth\n'
]

Если это имеет значение, тогда вы можетеизмените approval_regex так:

approval_regex = re.compile(
    r'Subject:.+\n.*approv(?:e|ed|al)',
    re.IGNORECASE|re.DOTALL|re.MULTILINE
)
0 голосов
/ 11 октября 2019

Учитывая, что вы преобразовали все это в строки текста и предполагаете, что формат почты соответствует, например, поле From - начало нового электронного письма и конец тела последнего сообщения, а поле Subject - последний заголовок письма и начало. тела. Вы можете просто установить флаг в True, когда увидите строку темы, указывающую, что следующие строки - это тело. Затем установите этот флаг, когда увидите строку От, указывающую, что тело закончилось.

Тогда, когда флаг истинен и вы находитесь в теле, вы можете делать все, что захотите. В приведенном ниже примере кода я просто собираю все строки из тела письма (исключая пустые строки) в список. Затем я могу сделать то, что мне нравится, с этим списком, например, проверить его на наличие строк, которые утверждают.

import re

emails = """
From: Jerrmy Bret <jeremy.brett@mnop.com>
To: Jonathan Small <j.small@xyz.com>
Date: 21 Sep 2019
Subject: Stuff

FYI...

From: Keven Koster <keve.koster@mnop.com>
To: Jerrmy Bret <jeremy.brett@mnop.com>
Date: 21 Sep 2019
Subject: Approval Required for Travel

Can't Approve as Ruth's approval is required

From: Jerrmy Bret <jeremy.brett@mnop.com>
To: Keven Koster <keve.koster@mnop.com>
Date: 21 Sep 2019
Subject: Approval Required for Travel

ok thanks Keven, will talk to Ruth

"""
body = False
email_bodys = []
for line in emails.splitlines():
    if not line:
        continue
    if line.startswith("From: "):
        body = False
    if body:
        email_bodys.append(line)
    if line.startswith("Subject: "):
        body = True
print("email bodys detected in the text are:\n\t" + "\n\t".join(email_bodys))

print("text in body which contain approve:")
for email_body in email_bodys:
    if re.findall(r'approve', email_body, re.I):
        print("\t" + email_body)

ВЫХОД

email bodys detected in the text are:
    FYI...
    Can't Approve as Ruth's approval is required
    ok thanks Keven, will talk to Ruth
text in body which contain approve:
    Can't Approve as Ruth's approval is required
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...