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.
Demo
import re m = re.search('(\\d{4})-(\\d\\d)-(\\d\\d)', 'due 2026-09-29') (m.groups(), m.groups(''))
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
| Name | Type | Required | Description |
|---|---|---|---|
| default | object | no (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
import re if m := re.fullmatch(r'(\d{4})-(\d{2})-(\d{2})', s): year, month, day = map(int, m.groups())
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()})
import re m = re.match(r'(?P<host>[\w.]+)(?::(?P<port>\d+))?', addr) parts = m.groupdict(default='80')
Examples
Pitfalls
import re re.search(r'(\w+)@\w+', 'ada@home').groups()[0]
import re re.search(r'(\w+)@\w+', 'ada@home').group(0)
import re host, tld = re.match(r'((\w+)\.(com|org))', 'site.org').groups()
import re host, tld = re.match(r'(?:(\w+)\.(com|org))', 'site.org').groups() (host, tld)
When to use
- Unpacking several groups into variables
- Turning a match into a dict of named fields
- One group → group(n)
- Every match in a text → findall (tuples) or finditer + groupdict()
Notes
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.