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.

re.Match methodPython 3 (all)Live demo
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

NameTypeRequiredDescription
group1, ...int | strno (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
None
7. 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.