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.
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
| Name | Type | Required | Description |
|---|---|---|---|
| pattern | str | re.Pattern | yes | The regular expression, as a raw string. |
| string | str | yes | The text; matching is tried at its first character only. |
| flags | re.RegexFlag | int | no (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
None3. 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
None6. 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.