How can I get a list of all possible matches in between non-greedy and greedy

给你一囗甜甜゛ 提交于 2019-12-12 19:57:43

问题


I have the string "I like lettuce and carrots and onions" in Python.

I thought I could get the following matches ["I like lettuce", "I like lettuce and carrots", "I like lettuce and carrots and onions"] by using a regex like .* and. (The regex should match any character up to " and".)

However, using the greedy version (.* and) gives me only the last match, and using the non-greedy version (.*? and) gives me only the first match.

How can I get all three matches?

(I do not need a regex solution.)


回答1:


For fun, use the string partition method in Python 3. It searches a string for a substring, and returns a 3-tuple. When there's a match, it's

(string before the match, the match, string after the match)

Once you're used to it, it's very pleasant - no indexing needed, and it makes it easy to get the right results. So while this code is longer than some other ways, you should be able to reason about it easily:

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

which prints

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



回答2:


I wouldn't use an re at all: What is wrong with:

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

which gives you a list from which you construct the desired strings.




回答3:


You can use simple splitting and construct strings without an expensive 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                        

If you need result in a list, go for a list-comprehension:

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


来源:https://stackoverflow.com/questions/50341554/how-can-i-get-a-list-of-all-possible-matches-in-between-non-greedy-and-greedy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!