Overview
Python’s re module uses Perl-style syntax but is not PCRE-compatible. Shared syntax (classes, quantifiers, lookarounds) and ready-made patterns are in regex-patterns. Compile patterns you reuse: re.compile() makes intent explicit and avoids repeated cache lookups.
Functions
Use fullmatch to validate and finditer to extract.
| Function | Returns | Use when |
|---|---|---|
re.search(p, s) | Match or None | Find the first match anywhere. |
re.match(p, s) | Match or None | The pattern must match at the start. |
re.fullmatch(p, s) | Match or None | The whole string must match (validation). |
re.findall(p, s) | List | All matches as strings, or tuples with several groups. |
re.finditer(p, s) | Iterator of matches | Matches with positions and groups. |
re.sub(p, repl, s) | String | Replace; repl may be a string with \g<name> or a function. |
re.split(p, s) | List | Split; capturing groups appear in the result. |
re.escape(s) | String | Escape text for use as a literal in a pattern. |
Flags
Pass re.I | re.M, or write them inline: (?i) for the whole pattern, (?i:...) for a group.
| Flag | Inline | Effect |
|---|---|---|
re.IGNORECASE | (?i) | Case-insensitive. |
re.MULTILINE | (?m) | ^ and $ match at every line. |
re.DOTALL | (?s) | . also matches newline. |
re.VERBOSE | (?x) | Ignore whitespace and # comments in the pattern. |
re.ASCII | (?a) | \w, \d, \s, \b match ASCII only (Unicode is the default for str). |
Python-specific syntax
Use the Python spellings; PCRE and JavaScript syntax differs.
| Syntax | Meaning |
|---|---|
(?P<name>...), (?P=name) | Named group, named backreference. JavaScript spells these (?<name>...) and \k<name>. |
\g<name> or \g<1> in repl | Group reference in a replacement string. |
a*+, (?>...) | Possessive quantifier, atomic group (3.11+). |
(?<=ab)c | Lookbehind must be fixed-width; the third-party regex module allows variable width. |
import re
m = re.search(r"(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})", "on 2026-05-14")
m.groupdict() # {'y': '2026', 'm': '05', 'd': '14'}
re.sub(r"\d+", lambda m: str(int(m[0]) * 2), "a1 b2") # 'a2 b4'
re.sub(r"(?P<last>\w+), (?P<first>\w+)", r"\g<first> \g<last>", "Smith, John")Gotchas
Avoid these; each returns a surprising match or hangs.
| Gotcha | Fix |
|---|---|
re.match anchors only the start. | Use re.fullmatch for validation. |
$ also matches before a trailing newline: match(r"a$", "a\n") succeeds. | Use fullmatch or \Z. |
\d and \w match non-ASCII digits and letters in str patterns. | Use [0-9] or re.ASCII. |
findall returns strings, one group’s text, or tuples depending on group count. | Use finditer and read .group(). |
re.split(r"(\s+)", s) keeps the separators. | Use (?:\s+) to drop them. |
| User text interpolated into a pattern changes its meaning. | Wrap it in re.escape(). |
Nested quantifiers like (a+)+ backtrack catastrophically on near-matches. | Rewrite the pattern; cap input length. |
A bytes pattern on str input raises TypeError. | Keep both the same type. |