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

2024-04-23 23:57:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图只返回bellow变量的第一个匹配

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)]))

Tags: inbrreforemailgroupitemsbody
3条回答

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,然后\s*匹配0+空格,(?:/\s*)?匹配/和0+空格的可选序列,>最后匹配>。因此,它可以匹配<br/><br><br />甚至<br / >。你知道吗

如果需要,可以将regex改进为this

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

现在您的正则表达式将在<符号处停止。你知道吗

正如评论所指出的,您的示例不是唯一的,因此功能似乎是正确的。或者在sub方法中添加一个项来删除<br>标记(然后set命令将删除重复的条目)。或者,如果您只需要来自email_body的第一个匹配,可以尝试使用regex包中的search方法。你知道吗

相关问题 更多 >