Как извлечь фрагмент, который может появляться несколько раз в строке - PullRequest
0 голосов
/ 10 января 2019

У меня есть электронные письма, в теле письма которых есть (из переменной email_body):

тело для 1-го электронного письма:

2.email:

3 электронная почта:

То же, что и для 2, просто другое имя машины

В этих письмах есть вложения, в которых также есть названия вакансий, я хочу получить название вакансии для каждого письма только один раз

for emailid in items:
    resp, data = conn.uid("fetch",emailid, "(RFC822)")
    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 machine name (string after word "MACHINE")
          regex1 = r'(?<!^)MACHINE:\s*(\S+)'

          a=re.findall(regex1 ,email_body)
          print (c)

пример тела сообщения из первого сообщения электронной почты для раздела MACHINE, полученного из кода Python, это переменная email_body, которую нужно искать с помощью регулярного выражения:

MACHINE: =^M
ldnmdsbatchxl01

Тело электронной почты для 2-го письма

MACHINE: p2prog06^M
MACHINE: p2prog06<br>^M

Разница в разрыве строки в 1-м теле письма

Токовый выход

['p1prog06', 'p1prog06<br>']
['p2prog06', 'p2prog06<br>']
['=', '=']

Как вы можете видеть, я получаю дублирующиеся вакансии и пропущенные имена из первого письма

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

['p1prog06']
['p2prog06']
['ldnmdsbatchxl01']

UPDATE

Благодаря @Predicate я удалил дубликаты для 2-го и 3-го электронных писем

regex2 = r'(?<=MACHINE: )\b\w+\b|$'

до сих пор не знаю, как получить работу с первого письма (разрыв строки)

1 Ответ

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

Попробуйте использовать это. С определенными границами слова. \w соответствует букве, цифрам и подчеркиванию. \b отмечает границу слова. \b не соответствует <, поэтому он заканчивается до тега <br>.

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

Вариант 1:

regex1 = r'(?<=MACHINE: )\b\w+\b'

Вариант 2:

Также возможно (если коды имеют формат <some letters and digits>< two digits>). Чтобы быть более конкретным:

regex1 = r'(?<=MACHINE: )\b\w+\d{2}\b'

Вариант 3:

Если есть несколько появлений одного и того же кода - один из способов справиться с ним - сопоставить только последнее появление имени задания. Мы создадим группу захвата (\w+\d{2}) и проверим, не появится ли она после сопоставления (?!.*\1):

regex1 = r'(?<=MACHINE: )\b(\w+\d{2})\b(?!.*\1)'

Вариант 4 (после получения дополнительной информации об окружающей среде):

're' модуль не поддерживает вид сзади разной длины. Лучше использовать регулярные выражения из pypi, но вы можете использовать этот трюк. Попробуй.

regex1 = r'(?<=MACHINE:\s=\s|..MACHINE:\s)\b(\w+)\b(?!.*\1)'

соответствует обоим адресам электронной почты и только один раз. один два

Конечно, вы все равно можете быть более конкретным, если знаете структуру ваших кодов и замените \w+ на \w+\d{2}. Это всегда хорошая практика. Но моего регулярного выражения должно быть достаточно для вас. Также вам, вероятно, нужно будет скомпилировать регулярное выражение с «однострочным флагом». regex1 = re.compile(r'<your regex>', re.DOTALL) и тогда делай regex1.findall(...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...