python正则表达式,仅返回第一个匹配项

时间:2019-01-11 14:04:59

标签: python regex

我正在尝试仅从波纹管变量中返回第一个匹配项

MACHINE: p1prog06<br>

MACHINE: p1prog06

使用以下表达式:

res = list(set([re.sub(r'=(?:\^M)?|[\r\n]+', '', m.group(1)) for m in re.finditer(r'\bMACHINE:\s*(.*(?:(?:\r\n?|\n)\S+)?)', email_body, re.M)]))

根据文档,

`list(set(res))`   

应该返回唯一值,但是我得到了

u'p1prog06', u'p1prog06<br><br>']

代码:

conn = imaplib.IMAP4_SSL("outlook.office365.com")
conn.login(user,pwd)
conn.select("test")

resp, items = conn.uid("search" ,None, '(OR (FROM "email@pexample.com) (FROM "email2@pexample.com"))')



items = items[0].split()
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 job name (string after word "JOB")
          regex1 = r'(?<!^)JOB:\s*(\S+)'
          #regex2 = r'\bMACHINE:\s*(.*(?:\s*^\d+)?)'
          #c=re.searchall(regex2, email_body, re.M)#,re.DOTALL)
          a=re.findall(regex1 ,email_body)
          #res = [re.sub(r'=(?:\^M)?|[\r\n]+', '', m.group(1)) for m in re.finditer(r'\bMACHINE:\s*(.*(?:(?:\r\n?|\n)\S+)?)', email_body, re.M)]
          res = list(set([re.sub(r'=(?:\^M\<br><br>)?|[\r\n]+', '', m.group(1)) for m in re.finditer(r'\bMACHINE:\s*(.*(?:(?:\r\n?|\n)\S+)?)', email_body, re.M)]))

3 个答案:

答案 0 :(得分:0)

正如评论所指出的那样,您的示例并非唯一,因此功能似乎正确。在sub方法中添加一个术语以删除<br>标签(然后您的set命令将删除重复的条目)。或者,如果您只想要email_body中的第一个匹配项,则可以尝试使用正则表达式包中的search方法。

答案 1 :(得分:0)

如果需要,可以将正则表达式改进为this

\bMACHINE:\s*([^<]*(?:(?:\r\n?|\n)\S+)?)

现在,您的正则表达式将在<符号处停止。

答案 2 :(得分:0)

您在array中使用的主正则表达式与re.finditer标记匹配。您只需使用<br>删除它们:

re.sub

您也可以像这样将它与re.sub(r'=(?:\^M)?|<br\s*(?:/\s*)?>|[\r\n]+', '', m.group(1)) ^^^^^^^^^^^^^^^^ 一起使用:

re.findall

注意res = list(set([re.sub(r'=(?:\^M)?|<br\s*(?:/\s*)?>|[\r\n]+', '', m) for m in re.findall(r'\bMACHINE:\s*(.*(?:(?:\r\n?|\n)\S+)?)', email_body)])) 是多余的,已被删除。

re.M模式匹配<br\s*(?:/\s*)?>,然后<br匹配0+空格,\s*匹配(?:/\s*)?和0+空格的可选序列,以及{ {1}}最终与/相匹配。因此,它可以匹配>><br/>甚至<br>