Match.groups

groups() returns all numbered groups (not group 0) as a tuple, ready to unpack; groupdict() returns the named groups as a dict. Both take a default for groups that did not participate — None unless you say otherwise.

re.Match methodPython 3 (all)Live demo
Common call
year, month, day = m.groups()
Returns
('2026', '09', '29') / {'year': '2026', …}
Replaces
m.group(1), m.group(2), … one by one
Watch out
groups() never includes group 0; groupdict() skips unnamed groups
Match.groups(defaultdefault — Value used for groups that did not take part in the match — often ''.type: object · default: None=None) / Match.groupdict(default=None)
→ tuple[str | None, ...] / dict[str, str | None]

Demo

Live evaluation
Every group, in order. Optional groups that were skipped show the default (None).
Try:
Inputs
patternstra regular expression with groups
textstrtext
Code
import re
m = re.search('(\\d{4})-(\\d\\d)-(\\d\\d)', 'due 2026-09-29')
(m.groups(), m.groups(''))
Result
(('2026', '09', '29'), ('2026', '09', '29'))

In the optional-parts case the fraction and percent groups did not match: groups() reports them as None, groups('') as empty strings. groupdict() contains only named groups — the (=) and (\w+) groups of the mixed case are left out — and a skipped named group (port) appears with the value None.

Parameters

NameTypeRequiredDescription
defaultobjectno (None)Value used for groups that did not take part in the match — often ''.

Return value

tuple[str | None, ...] / dict[str, str | None] — groups(): every group from 1 up. groupdict(): only the named groups. Unmatched groups get default.

Common patterns

Unpack straight into variables
The tuple length equals the number of groups.
import re
if m := re.fullmatch(r'(\d{4})-(\d{2})-(\d{2})', s):
    year, month, day = map(int, m.groups())
Parse into keyword arguments
groupdict() feeds a constructor directly.
import re
from datetime import date
m = re.fullmatch(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)', s)
d = date(**{k: int(v) for k, v in m.groupdict().items()})
Defaults for optional parts
Fill missing groups with a value that suits the next step.
import re
m = re.match(r'(?P<host>[\w.]+)(?::(?P<port>\d+))?', addr)
parts = m.groupdict(default='80')

Examples

1. All groups as a tuple
import re re.search(r'(\d{4})-(\d\d)-(\d\d)', 'due 2026-09-29').groups()
Returns
('2026', '09', '29')
2. Unmatched → None
import re re.match(r'(a)(b)?', 'a').groups()
Returns
('a', None)
3. With a default
import re re.match(r'(a)(b)?', 'a').groups('')
Returns
('a', '')
4. No groups → empty tuple
import re re.match(r'\d+', '42').groups()
Returns
()
5. Named groups as a dict
import re re.search(r'(?P<user>\w+)@(?P<host>\w+)', 'ada@home').groupdict()
Returns
{'user': 'ada', 'host': 'home'}
6. groupdict default
import re re.match(r'(?P<a>x)(?P<b>y)?', 'x').groupdict('-')
Returns
{'a': 'x', 'b': '-'}

Pitfalls

1. Expecting group 0 in groups()
groups() starts at group 1. Use group() for the whole match.
groups()[0]
import re
re.search(r'(\w+)@\w+', 'ada@home').groups()[0]
'ada'
group(0)
import re
re.search(r'(\w+)@\w+', 'ada@home').group(0)
'ada@home'
2. Unpacking the wrong number of groups
Every capturing group appears in the tuple — including an outer group you added around the others. Make it non-capturing.
outer ( )
import re
host, tld = re.match(r'((\w+)\.(com|org))', 'site.org').groups()
ValueError: too many values to unpack (expected 2)
outer (?: )
import re
host, tld = re.match(r'(?:(\w+)\.(com|org))', 'site.org').groups()
(host, tld)
('site', 'org')

When to use

Use it
  • Unpacking several groups into variables
  • Turning a match into a dict of named fields
Reach for something else
  • One group → group(n)
  • Every match in a text → findall (tuples) or finditer + groupdict()

Notes

CPython impl
match_groups / match_groupdict in Modules/_sre/_sre.c; groupdict iterates Pattern.groupindex, so keys come in the order the names appear in the pattern
default
Applies only to groups that did not participate; a group that matched the empty string gives '' regardless

FAQ

group() returns the whole match (or the groups you name); groups() returns a tuple of all capturing groups from 1 upward, without the whole match.