Match.group
The way to read what matched. group() or group(0) is the whole match, group(1) the first parenthesized group, group("name") a named one — and m[1] / m["name"] is shorthand since Python 3.6.
Common call
m.group(1)
Returns
'ada' — the text of group 1
Replaces
slicing the string with start/end indexes
Watch out
A group that did not take part returns None; a group that does not exist raises IndexError
Match.group([group1, ...])
→ str | None | tuple
Demo
Live evaluation
Type a group number or a group name.
Try:
Inputs
patternstra regular expression
textstrtext
groupint | strnumber or name
Code
import re m = re.search('(?P<user>[\\w.]+)@(?P<host>[\\w.]+)', 'mail ada@example.com now') m.group(0)
Result
'ada@example.com'
The demo passes the group as a number when you type digits and as a string otherwise — both work. An optional group that was skipped gives None (the (px)? case), while asking for a group the pattern does not have raises IndexError: no such group.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| group1, ... | int | str | no (0) | Group numbers (0 = whole match) or group names. With several arguments you get a tuple. |
Return value
str | None | tuple — One group: its text (None if it did not participate). Several groups: a tuple. No argument: the whole match.
Common patterns
Unpack several groups
group(1, 2) returns a tuple; so does groups().
import re if m := re.search(r'(\d+)x(\d+)', size): width, height = map(int, m.group(1, 2))
Default for an optional group
or supplies a fallback when the group is None.
import re m = re.match(r'(\d+)(px|em)?', css_value) unit = m.group(2) or 'px'
Index syntax
m[1] and m["name"] read like a sequence/dict lookup.
import re m = re.search(r'(?P<key>\w+)=(?P<value>\w+)', line) key, value = m['key'], m['value']
Examples
1. Whole match
import re
re.search(r'\d+', 'order 66').group()
Returns
'66'2. By number
import re
re.search(r'(\w+)@(\w+)', 'ada@home').group(2)
Returns
'home'3. By name
import re
re.search(r'(?P<user>\w+)@(?P<host>\w+)', 'ada@home').group('user')
Returns
'ada'4. Several at once
import re
re.search(r'(\w+)@(\w+)', 'ada@home').group(0, 1, 2)
Returns
('ada@home', 'ada', 'home')5. Index syntax
import re
m = re.search(r'(?P<user>\w+)@(\w+)', 'ada@home')
(m[0], m[1], m['user'])
Returns
('ada@home', 'ada', 'ada')6. Unmatched group is None
import re
print(re.match(r'(a)(b)?', 'a').group(2))
Returns
None7. A repeated group keeps the last
import re
re.match(r'(\w)+', 'abc').group(1)
Returns
'c'Pitfalls
1. Asking for a group the pattern does not have
Groups are counted by opening parentheses; (?:...) does not count.
group(2)
import re re.search(r'(?:\w+)@(\w+)', 'ada@home').group(2)
IndexError: no such group
group(1)
import re re.search(r'(?:\w+)@(\w+)', 'ada@home').group(1)
'home'
2. Expecting all repetitions of a group
A quantified group only remembers its last iteration. Use findall on the repeated part instead.
(\d+,?)+
import re re.match(r'(\d+,?)+', '1,22,333').group(1)
'333'
findall
import re re.findall(r'\d+', '1,22,333')
['1', '22', '333']
3. Calling group() on a failed search
There is no Match to read.
no check
import re re.search(r'(\d+)', 'none').group(1)
AttributeError: 'NoneType' object has no attribute 'group'
check first
import re m = re.search(r'(\d+)', 'none') m.group(1) if m else 'no number'
'no number'
When to use
Use it
- Reading the whole match or one specific group
- Several groups at once as a tuple: group(1, 2)
Reach for something else
- All groups → groups() or groupdict()
- Positions → start(), end(), span()
Notes
CPython impl
match_group in Modules/_sre/_sre.c; a group number is any integer-like index, a name is looked up in Pattern.groupindex
Indexing
m[g] (Match.__getitem__, Python 3.6+) accepts one group, same rules as group(g)
Repeats
For a group inside a repetition the last iteration wins — (\w)+ on "abc" gives "c"
FAQ
group() and group(0) are the entire match; group(1) is the text of the first capturing group, counted by opening parentheses from the left.