import re
text = "Order #1042 shipped 2026-09-27, order #1043 pending"
# All order numbers
re.findall(r"#(\d+)", text) # ['1042', '1043']
# Named groups
m = re.search(r"(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})", text)
m.group("y"), m.groupdict() # '2026', {'y': '2026', 'm': '09', 'd': '27'}
# Replace with a backreference
re.sub(r"#(\d+)", r"order-\1", text)
# Validate a whole value
bool(re.fullmatch(r"\d{5}(-\d{4})?", "94103-1234")) # TruePython regex
Everything you need from Python's built-in re module on one page: which function to call, how flags and groups work, and the gotchas that bite.
re functions
| Function | What it does | Example |
|---|---|---|
re.search(p, s) | First match anywhere, or None | re.search(r"\d+", "id 42") → <Match "42"> |
re.match(p, s) | Match at the start only | re.match(r"\d+", "id 42") → None |
re.fullmatch(p, s) | Whole string must match — use for validation | re.fullmatch(r"\d{5}", "94103") → <Match> |
re.findall(p, s) | List of all matches (or of group tuples) | re.findall(r"\d+", "1 a 22") → ["1", "22"] |
re.finditer(p, s) | Iterator of Match objects (positions + groups) | for m in re.finditer(...): m.start() |
re.sub(p, repl, s) | Replace matches; repl can be a function | re.sub(r"\s+", " ", s) |
re.split(p, s) | Split on a pattern | re.split(r"[,;]\s*", "a, b;c") → ["a","b","c"] |
re.compile(p, flags) | Pre-compile for reuse | EMAIL = re.compile(r"...", re.I) |
re.escape(s) | Escape user input for use in a pattern | re.escape("1+1") → "1\+1" |
Flags
| Constant | Inline | Effect |
|---|---|---|
re.I / re.IGNORECASE | (?i) | Case-insensitive |
re.M / re.MULTILINE | (?m) | ^ and $ at every line |
re.S / re.DOTALL | (?s) | . matches newline |
re.X / re.VERBOSE | (?x) | Whitespace ignored, # comments allowed |
re.A / re.ASCII | (?a) | \w \d \s match ASCII only |
Combine flags with |: re.compile(p, re.I | re.M).
Gotchas
findall returns groups, not whole matches
If the pattern has one group, findall returns that group; with several, a tuple per match. Use (?:…) for groups you don't need, or finditer and m.group(0).
match isn't "matches"
re.match(r"\d+", "abc123") is None because it only looks at the start. And re.match(r"\d+", "123abc") succeeds — it doesn't check the end. For "the whole string is digits" use re.fullmatch.
Unicode by default
In Python 3, \d matches any Unicode decimal digit (including Arabic-Indic ٣) and \w any letter in any script. Add re.ASCII when you mean 0–9 and A–Z.
Escaping user input
Building a pattern from a search box? Wrap it in re.escape() — otherwise a user typing ( raises an error and .* matches everything.
Python vs JavaScript syntax
- Named group: Python
(?P<name>…), JavaScript(?<name>…). - Backreference in replacement: Python
\1or\g<name>, JavaScript$1or$<name>. - Python has
\Aand\Zand inline flags(?i); JavaScript uses^/$withoutm, and flags after the closing slash. - Lookbehind in Python's
remust be fixed-width; JavaScript allows variable-width lookbehind.
Test the shared syntax live in the regex tester — its code panel outputs Python with named groups converted — or ask the AI generator for a pattern in Python flavor.
Questions
What is the difference between re.match, re.search and re.fullmatch?
re.match only matches at the start of the string, re.search scans for the first match anywhere, and re.fullmatch requires the whole string to match. For validation, use fullmatch.
Why should I use raw strings (r"...") for patterns?
In a normal Python string, backslashes are processed first: "\b" becomes a backspace character. r"\b" passes the two characters \ and b to the regex engine, which reads it as a word boundary.
How do named groups work in Python?
Define them with (?P<name>...), refer back with (?P=name), use \g<name> in re.sub replacements, and read them with m.group("name") or m.groupdict(). Python 3.x also accepts the (?<name>...) form only in the third-party regex module, not in re.
Can I test Python regex in the RegexKit tester?
Yes, for the shared syntax. The tester runs JavaScript's engine, which matches Python's re for classes, quantifiers, groups and lookarounds. Differences: Python uses (?P<name>) for named groups (the tester's code panel converts it), and has \A and \Z anchors and inline flags like (?i).