491

In a program I'm writing I have Python use the re.search() function to find matches in a block of text and print the results. However, the program exits once it finds the first match in the block of text.

How do I do this repeatedly where the program doesn't stop until ALL matches have been found? Is there a separate function to do this?

MackM
  • 2,906
  • 5
  • 31
  • 45
kjakeb
  • 6,810
  • 5
  • 20
  • 34
  • [Recursive REs](http://web.archive.org/web/20030206032122/http://www.puffinry.freeserve.co.uk/regex-extension.html) are a different beast. You want to repeat the search. – outis Jan 15 '11 at 04:29

1 Answers1

835

Use re.findall or re.finditer instead.

re.findall(pattern, string) returns a list of matching strings.

re.finditer(pattern, string) returns an iterator over MatchObject objects.

Example:

re.findall( r'all (.*?) are', 'all cats are smarter than dogs, all dogs are dumber than cats')
# Output: ['cats', 'dogs']

[x.group() for x in re.finditer( r'all (.*?) are', 'all cats are smarter than dogs, all dogs are dumber than cats')]
# Output: ['all cats are', 'all dogs are']
Mike Fogel
  • 3,127
  • 28
  • 22
Amber
  • 507,862
  • 82
  • 626
  • 550
  • 39
    `finditer` was what I was looking for. I'm surprised that one returns Match objects and the other strings. I was expecting to use a `match_all` or `match_iter` function. – dsclose Dec 07 '15 at 13:55
  • 41
    DISCLAIMER: those will find only **non-overlapping** matches – Antoine Lizée Sep 10 '16 at 22:16
  • 4
    @AntoineLizée, how does one find iterations WITH overlap? – Raksha May 10 '17 at 23:49
  • 25
    @Raksha - Use `re.search` in a loop. It'll return a `Match` object. You'll want to pass in `Match.start() + 1` as the `pos` argument for `re.search` for the next iteration of the loop. – ArtOfWarfare May 31 '17 at 17:31
  • 11
    If the match contains more than one group, `findall` will return a list of matching tuples, not a list of matching strings. – rodorgas Jun 12 '18 at 03:55
  • 1
    Here's an example to help visualizing: `re.findall( r'all (.*?) are', 'all cats are smarter than dogs, all dogs are dumber than cats')` (output: `['cats', 'dogs']`) – Fernando Wittmann Feb 24 '19 at 13:09
  • 3
    findall is not useful for named groups. – nurettin Apr 30 '19 at 13:23
  • @ArtOfWarfare but `re.search()` doesn't have a `pos` argument – von spotz Feb 08 '23 at 10:54