re.match

Anchored at the start, open at the end: re.match succeeds when the string BEGINS with the pattern. Also available as Pattern.match(string, pos, endpos), which anchors at pos instead.

re functionPython 3 (all)Live demo
Common call
re.match(r'\d+', '42 apples')
Returns
<re.Match object; span=(0, 2), match='42'> or None
Replaces
str.startswith when the prefix is a pattern
Watch out
Only position 0 — even with re.MULTILINE. Anywhere → re.search
re.match(patternpattern — The regular expression, as a raw string.type: str | re.Pattern · required, stringstring — The text; matching is tried at its first character only.type: str · required, flagsflags — Flags such as re.IGNORECASE. Not allowed with a compiled pattern.type: re.RegexFlag | int · default: 0=0)
→ re.Match | None

Demo

Live evaluation
Succeeds only if the text starts with something the pattern matches.
Try:
Inputs
patternstra regular expression
textstrtext
Code
import re
re.match('\\d+', '42 apples')
Result
<re.Match object; span=(0, 2), match='42'>

match wants the pattern at position 0 but does not care what follows: '[a-z]+' matches 'abc123' (span 0 to 3) — fullmatch does not. In the MULTILINE tab findall shows that ^ does match after the newline; match simply never looks there.

Parameters

NameTypeRequiredDescription
patternstr | re.PatternyesThe regular expression, as a raw string.
stringstryesThe text; matching is tried at its first character only.
flagsre.RegexFlag | intno (0)Flags such as re.IGNORECASE. Not allowed with a compiled pattern.

Return value

re.Match | None — A match that starts at position 0 (it need not reach the end), or None.

Common patterns

Parse a line that starts with a known shape
Groups pull the fields out of the prefix; the rest of the line is ignored.
import re
if m := re.match(r'(\d{4})-(\d{2})-(\d{2}) ', line):
    year, month, day = map(int, m.groups())
A tokenizer loop with pos
Pattern.match(string, pos) anchors at pos — step through a string token by token.
import re
TOKEN = re.compile(r'\s*(\d+|[-+*/()])')
pos = 0
while m := TOKEN.match(expr, pos):
    tokens.append(m.group(1))
    pos = m.end()

Examples

1. Matches at the start
import re re.match(r'\d+', '42 apples')
Returns
<re.Match object; span=(0, 2), match='42'>
2. Not at the start: None
import re print(re.match(r'\d+', 'apples: 42'))
Returns
None
3. Does not need the end
import re re.match(r'[a-z]+', 'abc123').group()
Returns
'abc'
4. Groups from the prefix
import re re.match(r'(get|set) (\w+)', 'set volume 11').groups()
Returns
('set', 'volume')
5. MULTILINE does not help
import re print(re.match(r'^b', 'a\nb', re.MULTILINE))
Returns
None
6. Pattern.match anchors at pos
import re re.compile(r'\d+').match('ab12', 2)
Returns
<re.Match object; span=(2, 4), match='12'>

Pitfalls

1. Validating input with match
match accepts anything that merely starts right. Use fullmatch (or \Z) to require the whole string.
re.match
import re
bool(re.match(r'\d{3}', '1234567'))
True
re.fullmatch
import re
bool(re.fullmatch(r'\d{3}', '1234567'))
False
2. Expecting match to search
The text contains a number, but not at position 0.
re.match
import re
print(re.match(r'\d+', 'total: 42'))
None
re.search
import re
re.search(r'\d+', 'total: 42')
<re.Match object; span=(7, 9), match='42'>

When to use

Use it
  • The text must begin with the pattern (a prefix, a command, a line header)
  • Tokenizing with Pattern.match(string, pos) step by step
Reach for something else
  • Pattern can occur anywhere → re.search
  • Validating a whole value → re.fullmatch
  • Fixed prefix → str.startswith

Notes

CPython impl
Pattern.match runs the matcher once, at pos (sre_match in Modules/_sre/_sre.c); no scanning
pos
Pattern.match(string, pos) anchors at pos, but ^ still means the start of the string, so r"^a" with pos > 0 never matches
vs ^
In search, ^ with re.MULTILINE can match after every newline; re.match only ever tries position 0 (or pos)

FAQ

re.match only tries at the beginning of the string. If the pattern occurs later, use re.search.