如何在非贪婪和贪婪之间获得所有可能匹配的列表

时间:2018-05-15 02:39:02

标签: python regex greedy non-greedy

我在Python中有字符串"I like lettuce and carrots and onions"

我认为我可以使用像["I like lettuce", "I like lettuce and carrots", "I like lettuce and carrots and onions"]这样的正则表达式获得以下匹配.* and。 (正则表达式应匹配任何字符,直到"和"。)

但是,使用贪婪版本(.* and)只给我最后一场比赛,使用非贪婪版本(.*? and)只给我第一场比赛。

我怎样才能获得所有三场比赛?

(我不需要正则表达式解决方案。)

3 个答案:

答案 0 :(得分:2)

为了好玩,请在Python 3中使用字符串partition方法。它在字符串中搜索子字符串,并返回3元组。当匹配时,它是

  

(匹配前的字符串,匹配,匹配后的字符串)

一旦你习惯了它,它非常令人愉快 - 不需要索引,它可以很容易地得到正确的结果。因此,虽然此代码比其他方式更长,但您应该能够轻松地对其进行推理:

def findallprefix(s, sep):
    sofar = ""
    while True:
        head, matched, s = s.partition(sep)
        if matched:
            assert matched == sep
            sofar += head
            yield sofar
            sofar += matched
        else:
            break

s = "I like lettuce and carrots and onions and dressing."
for match in findallprefix(s, " and"):
    print(repr(match))

打印

'I like lettuce'
'I like lettuce and carrots'
'I like lettuce and carrots and onions'

答案 1 :(得分:1)

我根本不会使用re:出了什么问题:

p = "I like lettuce and carrots and onions and dressing.".split("and")

,它为您提供了构建所需字符串的列表。

答案 2 :(得分:1)

您可以使用简单的拆分和构造字符串而无需昂贵的regex

s = "I like lettuce and carrots and onions and dressing."

splitted = s.split('and')
for x in range(1, len(splitted)):
    print('and'.join(splitted[:x]))

# I like lettuce
# I like lettuce and carrots                                  
# I like lettuce and carrots and onions                        

如果您需要列表中的结果,请转到列表理解:

>>> s = "I like lettuce and carrots and onions and dressing."
>>> splitted = s.split('and')
>>> ['and'.join(splitted[:x]) for x in range(1, len(splitted))]
['I like lettuce ', 'I like lettuce and carrots ', 'I like lettuce and carrots and onions ']