如何匹配python正则表达式的替代品

时间:2017-03-18 18:09:00

标签: python regex string

给出字符串1:

''' TOM 喜欢去游泳 玛丽 喜欢去操场 JANE 喜欢去购物''

我想在两个名字之间捕捉文字。无论是汤姆和玛丽还是汤姆和简。如果玛丽出现在简之前,我想捕捉汤姆和玛丽之间的文字。但是,如果Jane首先出现,我想捕获Tom和Jane之间的文本。

我写了以下代码:

text = re.compile(r'''(
            TOM\s*
            ([\w\W]+)\s*
            JANE|MARY
            )''', re.VERBOSE)

text_out = text.search(string).group(1)

然而,这段代码会给我Tom和Jane之间的文字,即使Mary出现在第一位。我知道这是因为管道功能从左到右读取,因此首先匹配Jane。有没有办法对此进行编码,这取决于谁首先出现在文本中?

例如,在string2中: "''' TOM 喜欢去游泳 JANE 喜欢去购物 玛丽 喜欢去操场 '''

我想捕获Tom和Jane之间的string2文本。

1 个答案:

答案 0 :(得分:4)

您需要修复您的更改,必须使用非捕获组(?:JANE|MARY)附加,并使用带[\w\W]的惰性量词(我将替换为.*并使用re.DOTALL修饰符使点也匹配换行符:

(?s)TOM\s*(.+?)\s*(?:JANE|MARY)

请参阅regex demo

如果没有(?:...|...),你的正则表达式匹配Tom,那么任何1个字符都尽可能多(也就是说,正则表达式抓住整个字符串,然后回溯以匹配最后一次出现的字符串后续子模式JANE)和JANEMARY子字符串。现在,固定的正则表达式匹配:

  • (?s) - DOTALL内联修饰符
  • TOM - 文字字符序列
  • \s* - 0+ whitespaces
  • (.+?) - 第1组(捕获):任意1个字符,尽可能,直到第一次出现的后续子模式....
  • \s* - 0+ whitespaces
  • (?:JANE|MARY) - JANEMARY子字符串。