Python - регулярные выражения - часть поиска находится в той же строке, часть в следующей - PullRequest
0 голосов
/ 11 января 2019

У меня есть 3 электронных письма, которые имеют следующее в теле письма:

1-е письмо

2-е письмо

3-е письмо

= 

означает новую строку. Есть 3 случая:

Дело 1 имя машины находится на следующей строке

* * Пример тысяча двадцать-одина * * тысяча двадцать-дв
 MACHINE: =
ldnmdsbatchxl01

Дело 2

имя машины находится на той же строке:

MACHINE: p2prog06

Дело 3

Часть машины находится в той же строке, часть - в следующей строке

MACHINE: p1prog=
07

Следующие работы для первых 2 и частичные для третьего случая: regex2 = r'\bMACHINE:\s*(?:=.*)?\s*([^<^\n ]+)

в 3-м я получаю p1prog=

> Желаемый выход:

p1prog07
ldnmdsbatchxl01
p2prog06

Спасибо

if resp == 'OK':
        email_body = data[0][1].decode('utf-8')
        mail = email.message_from_string(email_body)
        #get all emails with words "PA1" or "PA2" in subject
        if mail["Subject"].find("PA1") > 0 or mail["Subject"].find("PA2") > 0:
                  #search email body for job name (string after word "JOB")
          regex1 = r'(?<!^)JOB:\s*(\S+)'
          regex2 = r'\bMACHINE:\s*(?:=.*)?\s*([^<^\n ]+)|$'
          c=re.findall(regex2, email_body)[0]#,re.DOTALL)
          a=re.findall(regex1 ,email_body)

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Вы можете использовать

import re
email = 'MACHINE: =\nldnmdsbatchxl01\n\n\nMACHINE: p2prog06\n\n\nMACHINE: p1prog=^M\n07'
res = list(set([re.sub(r'=(?:\^M)?|[\r\n]+', '', x) for x in re.findall(r'\bMACHINE:\s*(.*(?:(?:\r\n?|\n)\S+)?)', email, re.M)]))
print(res)
# => ['ldnmdsbatchxl01', 'p2prog06', 'p1prog07']

См. Демоверсию Python

Используемое регулярное выражение: \bMACHINE:\s*(.*(?:(?:\r\n?|\n)\S+)?):

  • \bMACHINE - целое слово MACHINE
  • : - : char
  • \s* - 0+ пробелов
  • (.*(?:(?:\r\n?|\n)\S+)?) - Группа 1 (эта подстрока будет возвращена re.findall):
    • .* - 0+ символов, кроме символов разрыва строки
    • (?:(?:\r\n?|\n)\S+)? - необязательная подстрока:
      • (?:\r\n?|\n) - последовательность разрыва строки CRLF, LF или CR
      • \S+ - 1+ непробельных символов

re.sub(r'=(?:\^M)?|[\r\n]+', '', x) удаляет символы = или =^M и CR / LF из значения группы 1.

Чтобы получить уникальные значения, используйте list(set(res)).

0 голосов
/ 11 января 2019

Краткий ответ:

regexp = re.compile('MACHINE:\s={0,1}\s{0,1}((\S+=\^M\s\S+|\S+))')
value = regexp.search(data)[1]
value.replace('=^M\n', ''))

Длинный ответ:

Предположим, у нас есть данные из ваших примеров:

data = """
BFAILURE       JOB: p2_batch_excel_quants_fx_daily_vol_check_0800 MACHINE: =
ldnmdsbatchxl01 EXITCODE:  268438455
(...)
RUNALARM      JOB: p2_credit_qv_curve_snap MACHINE: p2prog06

Attachments:
(...)
[11/01/2019 08:15:09]      CAUAJM_I_40245 EVENT: ALARM            ALARM: JO=^M
BFAILURE       JOB: p1_static_console_row_based_permissions MACHINE: p1prog=^M
07        EXITCODE:  1<br>^M
"""

Тогда мы можем использовать код:

import re

regexp = re.compile('MACHINE:\s={0,1}\s{0,1}((\S+=\^M\s\S+|\S+))')

for d in data.split("(...)"):
    value = regexp.search(d)[1]
    print(value.replace('=^M\n', ''))

Как вы видите, регулярное выражение соответствует = ^ M \ n, поэтому нам нужно удалить его после.

выход:

ldnmdsbatchxl01
p2prog06
p1prog07

EDIT:

если ваши данные содержат много тел электронной почты в одной строке:

import re

regexp = re.compile('MACHINE:\s={0,1}\s{0,1}((\S+=\^M\s\S+|\S+))')

matches = regexp.findall(data)
print(matches)

print('---')

for m in matches:
    print(m[0].replace('=^M\n', ''))

продукты:

[('ldnmdsbatchxl01', 'ldnmdsbatchxl01'), ('p2prog06', 'p2prog06'), ('p1prog=^M\n07', 'p1prog=^M\n07')]
---
ldnmdsbatchxl01
p2prog06
p1prog07
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...