如何提取可在字符串中多次出现的片段

时间:2019-01-10 11:12:20

标签: python regex

我的电子邮件正文中有以下电子邮件(来自email_body变量):

body(第一封电子邮件):

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)

从python代码检索到的MACHINE部分的第一封电子邮件的邮件正文示例,这是email_body变量,需要通过正则表达式进行搜索:

MACHINE: =^M
ldnmdsbatchxl01

第二封电子邮件的电子邮件正文

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

区别在于第一封电子邮件正文中的换行符

当前输出

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

如您所见,我收到第一封电子邮件中的重复工作,并且缺少工作名称

所需的输出

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

更新

由于@Predicate,我消除了第二和第三封电子邮件的重复

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

仍然不知道如何从第一封电子邮件(换行)中获得工作

1 个答案:

答案 0 :(得分:0)

尝试使用此功能。具有定义的单词边界。 \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中的regex,但是您可以使用此技巧。试试吧。

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

只匹配两个电子邮件。 one two

当然,如果您知道代码的结构并将\w+替换为\w+\d{2},则仍然可以更加具体。它始终是一个好习惯。但是我的正则表达式足以满足您的需求。另外,您可能需要使用“单行标志”来编译正则表达式。 regex1 = re.compile(r'<your regex>', re.DOTALL)然后执行regex1.findall(...