Drop the * from your regex (so it matches exactly one instance of your pattern). Then use either re.findall(...) or re.finditer (see here) to return all matches.

It sounds like you're essentially building a recursive descent parser. For relatively simple parsing tasks, it is quite common and entirely reasonable to do that by hand. If you're interested in a library solution (in case your parsing task may become more complicated later on, for example), have a look at pyparsing.

Answer from phooji on Stack Overflow
🌐
Python documentation
docs.python.org › 3 › howto › regex.html
Regular Expression HOWTO — Python 3.14.3 documentation
For example, an RFC-822 header line is divided into a header name and a value, separated by a ':', like this: From: author@example.com User-Agent: Thunderbird 1.5.0.9 (X11/20061227) MIME-Version: 1.0 To: editor@example.com · This can be handled by writing a regular expression which matches an entire header line, and has one group which matches the header name, and another group which matches the header’s value.
🌐
PYnative
pynative.com › home › python › regex › python regex capturing groups
Python Regex Capturing Groups – PYnative
April 12, 2021 - Python regex capturing groups match several distinct patterns inside the same target string using group() and groups()
🌐
Regular-Expressions.info
regular-expressions.info › named.html
Regex Tutorial: Named Capturing Groups - Backreference Names
They can be particularly difficult to maintain as adding or removing a capturing group in the middle of the regex upsets the numbers of all the groups that follow the added or removed group. Python’s re module was the first to offer a solution: named capturing groups and named backreferences. (?P<name>group) captures the match of group into the backreference “name”. name must be an alphanumeric sequence starting with a letter.
🌐
Finxter
blog.finxter.com › home › learn python blog › python regex named groups
Python Regex Named Groups - Be on the Right Side of Change
October 27, 2022 - To maximize readability of your regex programs, you can use named groups in the form of (?P<name>...), name being the string identifier associated with that particular named group. ... For example, you match the name and income of a string 'Alice 97000' using two whitespace-separated named groups (?P<name>.*) and (?P<income>.*).
🌐
Timothygebhard
timothygebhard.de › posts › named-groups-in-regex-in-python
Named groups for regex in Python · Timothy Gebhard
So without further ado, here’s the example code for named group using Python’s re module: import re test_string = 'alpha=1.4 beta=2 gamma=43 delta=None' pattern = re.compile('beta=(?P<beta>\d+).*delta=(?P<delta>.+)') matches = pattern.match(test_string) if matches is not None: beta = matches.group('beta') delta = matches.group('delta')
🌐
UC Berkeley Statistics
stat.berkeley.edu › ~spector › extension › python › notes › node84.html
Multiple Matches
>>> addrtext = 'Python web site: 132.151.1.90 \ ... Google web site: 216.239.35.100' >>> newtext = addrtext >>> ippat = re.compile(r'\d+(?:\.\d+){3}') >>> mtch = ippat.search(newtext) >>> count = 1 >>> while mtch: ... print 'match %d: %s' % (count,mtch.group(0)) ...
🌐
Python documentation
docs.python.org › 3 › library › re.html
re — Regular expression operations — Python 3.14.3 ...
Escapes such as \n are converted to the appropriate characters, and numeric backreferences (\1, \2) and named backreferences (\g<1>, \g<name>) are replaced by the contents of the corresponding group. The backreference \g<0> will be replaced by the entire match. Changed in version 3.5: Unmatched groups are replaced with an empty string. ... Returns one or more subgroups of the match. If there is a single argument, the result is a single string; if there are multiple arguments, the result is a tuple with one item per argument.
Find elsewhere
🌐
TutorialsPoint
tutorialspoint.com › how-do-we-use-python-regular-expression-named-groups
How do we use Python Regular Expression named groups?
Following is the Python example, which demonstrates how to match a particular pattern in a string using groups - import re input_string = "Tutorials Point began as a single HTML tutorial and has since expanded to offer a wide range of online courses and tutorials. It was established on 2014-06-12." regexp = r"(\d{4})-(\d{2})-(\d{2})" match = re.search(regexp, input_string) if match: print("Found date in the given text:", match.group(0)) print("Year:", match.group(1)) print("Month:", match.group(2)) print("Day:", match.group(3))
🌐
Safjan
safjan.com › home › note › python regex named groups
Python Regex Named Groups
July 11, 2023 - In Python regex, match.groupdict() is a method that returns a dictionary containing all the named groups of a regular expression match.
🌐
Spark By {Examples}
sparkbyexamples.com › home › python › python regex groups
Python regex groups - Spark By {Examples}
May 31, 2024 - If a match is found, we access the captured groups using the match.group() method. Group 1 corresponds to the first set of parentheses, Group 2 corresponds to the second set of parentheses, and Group 3 corresponds to the third set of parentheses in the pattern. ... Named groups in Python regex allow us to assign names to specific capturing groups within a pattern.
🌐
Learning About Electronics
learningaboutelectronics.com › Articles › Named-groups-with-regular-expressions-in-Python.php
How to Use Named Groups with Regular Expressions in Python
We then look up matches with the statement, matches= re.search(regex, string1) ... The advantage to named groups is that it adds readability and understandability to the code, so that you can easily see what part of a regular expression match is being referenced. And this is how we can use named groups with regular expressions in Python.
🌐
Finxter
blog.finxter.com › home › learn python blog › python re groups
Python Re Groups - Be on the Right Side of Change
May 5, 2023 - An example regex that does this is 'a(b|c)'. The whole content enclosed in the opening and closing parentheses is called matching group (or capture group). You can have multiple matching groups in a single regex.
🌐
Imperial College London
python.pages.doc.ic.ac.uk › lessons › regex › 07-groups › 02-named.html
Advanced Lesson 1: Regular Expressions > Named groups
This is done with (?P<name> ). Note that name must be a valid Python identifier. The names make the groups more semantically meaningful, rather than having to refer to them by a number. As usual, try out the examples yourself and make sure you understand what each line is doing (should be self-explanatory). Consult the documentation if you have doubts. >>> pattern = "Name: (?P<name>[A-Za-z ]+); Phone: (?P<phone>\d+)" >>> string = "Name: Josiah Wang; Phone: 012345678" >>> match = re.match(pattern, string) >>> print(match) <re.Match object; span=(0, 35), match='Name: Josiah Wang; Phone: 012345678'> >>> match.group("name") 'Josiah Wang' >>> match.group("phone") '012345678' >>> match.group(1) 'Josiah Wang' >>> match.group(2) '012345678' >>> match.groupdict() {'name': 'Josiah Wang', 'phone': '012345678'}
🌐
w3reference
w3reference.com › blog › regular-expression-group-capture-with-multiple-matches
Regular Expression Group Capture: How to Get Multiple Matches Without Overwriting (Python Example) — w3reference.com
Use match.group('name') or 'default' to avoid KeyError. Test Regex with Tools: Validate regex patterns using tools like regex101.com to ensure groups capture correctly. Avoid Overlapping Matches: Use non-greedy quantifiers (e.g., .*?) or lookaheads to prevent overlapping matches from being skipped. Capturing multiple regex group matches without overwriting is critical for parsing structured data from text. Python...
🌐
Python
docs.python.org › 2.2 › lib › match-objects.html
4.2.5 Match Objects
If a group is contained in a part of the pattern that did not match, the corresponding result is None. If a group is contained in a part of the pattern that matched multiple times, the last match is returned. If the regular expression uses the (?P<name>...) syntax, the groupN arguments may ...
🌐
LearnByExample
learnbyexample.github.io › py_regular_expressions › working-with-matched-portions.html
Working with matched portions - Understanding Python re(gex)?
See docs.python: Match Objects for details. >>> pat = re.compile(r'hi.*bye') >>> m = pat.search('This is goodbye then', 1, 15) >>> m.pos 1 >>> m.endpos 15 >>> m.re re.compile('hi.*bye') >>> m.string 'This is goodbye then' The groupdict() method will be discussed in the Named capture groups section and the expand() method will be covered in the Match.expand() section.