# Python - regular expressions - part of the search patern is in same line, part is in the next one

I have 3 emails which have following in email body:

2nd email

3rd email

``````=
``````

means new line.There are 3 cases:

Case 1 machine name is on the next line

Example

`````` MACHINE: =
ldnmdsbatchxl01
``````

Case 2

machine name is on the same line:

``````MACHINE: p2prog06
``````

Case 3

Part of the machine is in the same line, part is in next line

``````MACHINE: p1prog=
07
``````

Following works for first 2 and partial for 3rd case:`regex2 = r'\bMACHINE:\s*(?:=.*)?\s*([^<^\n ]+)`

in 3rd i'm getting `p1prog=`

> Desired output:

``````p1prog07
ldnmdsbatchxl01
p2prog06
``````

Thanks

``````if resp == 'OK':
email_body = data.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)#,re.DOTALL)
a=re.findall(regex1 ,email_body)
``````
• Try `m=re.search(r'\bMACHINE:\s*(.*(?:\s*^\d+)?)', s, re.M)`, `if m: print(m.group(1).replace("\n", "").replace("\r", ""))` (regex demo) – Wiktor Stribiżew Jan 11 at 11:10
• Thanks, it works for 3rd case, but it doesn't print 1st and 2nd, how to combine your regex with mine ? – user10205566 Jan 11 at 11:16
• See ideone.com/cLw0kp. It prints all of them. – Wiktor Stribiżew Jan 11 at 11:19
• email_body is variable where all email bodies with MACHINE names are stored (examples are in link i posted):`for s in email_body: #print s m=re.search(r'\bMACHINE:\s*(.*(?:\s*^\d+)?)', s, re.M) if m: print("Result: " + m.group(1).replace("\n", "").replace("\r", ""))` and getting nothing – user10205566 Jan 11 at 11:28
• Maybe ideone.com/TnOX0I will work? – Wiktor Stribiżew Jan 11 at 11:30

## 2 Answers

You may use

``````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']
``````

See the Python demo

The regex used is `\bMACHINE:\s*(.*(?:(?:\r\n?|\n)\S+)?)`:

• `\bMACHINE` - whole word `MACHINE`
• `:` - a `:` char
• `\s*` - 0+ whitespaces
• `(.*(?:(?:\r\n?|\n)\S+)?)` - Group 1 (this substring will be returned by `re.findall`):
• `.*` - 0+ chars other than line break chars
• `(?:(?:\r\n?|\n)\S+)?` - an optional substring:
• `(?:\r\n?|\n)` - a CRLF, LF or CR line break sequence
• `\S+` - 1+ non-whitespace chars

The `re.sub(r'=(?:\^M)?|[\r\n]+', '', x)` removes `=` or `=^M` and CR/LF symbols from the Group 1 value.

To get unique values, use `list(set(res))`.

• yes, that did the trick !!, thanks a lot Wiktor – user10205566 Jan 11 at 12:18

### Short answer:

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

### Long answer:

Assume we have data from your examples:

``````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
"""
``````

Then we may use code:

``````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)
print(value.replace('=^M\n', ''))
``````

As you see regexp match =^M\n too, so we need to remove it after.

output:

``````ldnmdsbatchxl01
p2prog06
p1prog07
``````

### EDIT:

if your data contains many email bodies in one string:

``````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.replace('=^M\n', ''))
``````

produce:

``````[('ldnmdsbatchxl01', 'ldnmdsbatchxl01'), ('p2prog06', 'p2prog06'), ('p1prog=^M\n07', 'p1prog=^M\n07')]
---
ldnmdsbatchxl01
p2prog06
p1prog07
``````
• `email_body = data.decode('utf-8') regexp = re.compile('MACHINE:\s={0,1}\s{0,1}((\S+=\^M\s\S+|\S+))') for d in email_body: value = regexp.search(d) print(value)` getting bunch of None email_body is list containing message body for multiple emails – user10205566 Jan 11 at 11:47
• if you have many emails bodies in one string try: `regexp = re.compile('MACHINE:\s={0,1}\s{0,1}((\S+=\^M\s\S+|\S+))') machines =regexp.findall(email_body)` – Adam Puza Jan 11 at 11:51
• getting [(u'p1prog=', u'p1prog='), (u'p1prog=', u'p1prog=')] [(u'=', u'='), (u'=', u'=')] – user10205566 Jan 11 at 11:56
• `(u'p1prog=', u'p1prog=')` is what is expected. Look at edited post above. And about `u'=',` - I can't help without knowing how look line that produces this. – Adam Puza Jan 11 at 11:59
• no, i need p1prog07 and ldnmdsbatchxl01 ( i have these two in email_body variable) – user10205566 Jan 11 at 12:01
{"ft_lang_label":"__label__en","ft_lang_prob":0.5562964,"math_prob":0.93098617,"size":1314,"snap":"2019-13-2019-22","text_gpt3_token_len":466,"char_repetition_ratio":0.114503816,"word_repetition_ratio":0.011627907,"special_character_ratio":0.3888889,"punctuation_ratio":0.23648648,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.99379927,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2019-05-19T21:21:24Z\",\"WARC-Record-ID\":\"<urn:uuid:b7956ec5-54ba-4a97-8532-a98382e92241>\",\"Content-Length\":\"136776\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:29d0ca3e-b660-4ac9-9585-55f375a12a3b>\",\"WARC-Concurrent-To\":\"<urn:uuid:853b4056-0bc9-49b7-a054-fda707f36fc9>\",\"WARC-IP-Address\":\"151.101.193.69\",\"WARC-Target-URI\":\"https://stackoverflow.com/questions/54145273/python-regular-expressions-part-of-the-search-patern-is-in-same-line-part-i\",\"WARC-Payload-Digest\":\"sha1:6RQKHEJSDLYB22PF35GVJ4G7AMP2E6IZ\",\"WARC-Block-Digest\":\"sha1:RPMITTMMGO6SMPZEXRXEUXHJSNMQVPR7\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2019/CC-MAIN-2019-22/CC-MAIN-2019-22_segments_1558232255165.2_warc_CC-MAIN-20190519201521-20190519223521-00428.warc.gz\"}"}