PythonMastery
reference 5 min read · lesson 10 of 16 in Reference

Python Regex Cheat Sheet

1 · The lesson

read

Quick reference for Python's re module. Always use raw strings: r"\d+". For the full tutorial see Regex.

1. The Functions

python
import re

re.search(pat, s)       # first match anywhere   -> Match | None
re.match(pat, s)        # only at start          -> Match | None
re.fullmatch(pat, s)    # entire string          -> Match | None
re.findall(pat, s)      # all matches            -> list[str] | list[tuple]
re.finditer(pat, s)     # all matches            -> iterator[Match]
re.sub(pat, repl, s)    # substitute             -> str
re.subn(pat, repl, s)   # substitute + count     -> (str, int)
re.split(pat, s)        # split on pattern       -> list[str]
re.compile(pat, flags)  # compile once, reuse    -> Pattern
+ setup added so this can run · defines pat, s, repl, flags
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

pat = _AutoMock('pat')
s = _AutoMock('s')
repl = _AutoMock('repl')
flags = _AutoMock('flags')

2. Character Classes

TokenMatches
.Any char except newline (with re.S includes newline)
\dDigit [0-9]
\DNon-digit
\wWord char [A-Za-z0-9_]
\WNon-word
\sWhitespace [ \t\n\r\f\v]
\SNon-whitespace
[abc]Any of a, b, c
[^abc]None of a, b, c
[a-z]Range a through z

3. Quantifiers

TokenMeaning
*0 or more (greedy)
+1 or more (greedy)
?0 or 1 (greedy)
{n}Exactly n
{n,}n or more
{n,m}n to m
*? +? ?? {n,m}?Non-greedy (minimal) versions

4. Anchors

TokenMeaning
^Start of string (or line with re.M)
$End of string (or line with re.M)
\AStart of string only
\ZEnd of string only
\bWord boundary
\BNon-word boundary

5. Groups

SyntaxMeaning
(...)Capturing group, numbered from 1
(?:...)Non-capturing group (no number)
(?P<name>...)Named capturing group
(?P=name)Backreference by name
\1, \2 ...Backreference by number
(?=...)Positive lookahead
(?!...)Negative lookahead
(?<=...)Positive lookbehind
(?<!...)Negative lookbehind
python
m = re.search(r"(?P<user>\w+)@(?P<domain>\S+)", "ada@dev.io")
m.group("user")        # 'ada'
m.group("domain")      # 'dev.io'
m.groupdict()          # {'user': 'ada', 'domain': 'dev.io'}
+ setup added so this can run · defines re
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

re = _AutoMock('re')

6. Flags

FlagShortEffect
re.IiCase-insensitive
re.Mm^ / $ match at every line
re.Ss. matches newline
re.XxVerbose: ignore whitespace and # comments in pattern
re.AaASCII-only \w \d \s \b
re.LLLocale-aware (rare; avoid)
python
pat = re.compile(r"""
    (?P<area>\d{3}) -        # area code
    (?P<num>\d{4})           # local number
""", re.X)
pat.search("dial 415-9000").groupdict()  # {'area': '415', 'num': '9000'}
+ setup added so this can run · defines re
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

re = _AutoMock('re')

7. Substitution

python
re.sub(r"\s+", " ", "hi   there\nyou")          # 'hi there you'

# Reference groups in replacement
re.sub(r"(\w+)@(\w+)", r"\2:\1", "ada@dev")     # 'dev:ada'
re.sub(r"(?P<n>\d+)", r"<\g<n>>", "a1 b22")     # 'a<1> b<22>'

# Callback for complex replacement
re.sub(r"\d+", lambda m: str(int(m.group()) * 2), "1 and 2")  # '2 and 4'
+ setup added so this can run · defines re
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

re = _AutoMock('re')

8. Pre-compile for Reuse

python
WORD = re.compile(r"\b\w+\b")
for line in lines:
    for m in WORD.finditer(line):
        ...
+ setup added so this can run · defines lines, re
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

lines = ["alpha", "beta", "gamma"]
re = _AutoMock('re')

Common Patterns

GoalPattern
Email (loose)r"[\w.+-]+@[\w-]+(?:\.[\w-]+)+"
URL (loose)r"https?://[^\s]+"
Signed integerr"-?\d+"
Decimal numberr"-?\d+(?:\.\d+)?"
Hex colourr"#[0-9A-Fa-f]{6}"
Date YYYY-MM-DDr"\d{4}-\d{2}-\d{2}"
IPv4 (loose)r"\b(?:\d{1,3}\.){3}\d{1,3}\b"
Leading/trailing spacer"^\s+|\s+$"
HTML tagr"<[^>]+>"
UUIDr"[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}"
Quoted stringr'"(?:[^"\\]|\\.)*"'
python
# Putting one to use
emails = re.findall(r"[\w.+-]+@[\w-]+(?:\.[\w-]+)+", text)
+ setup added so this can run · defines text, re
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

text = _AutoMock('text')
re = _AutoMock('re')

Common Errors

Error / SymptomCauseFix
re.search returns None but you expected a matchre.match anchors at startUse re.search for "anywhere"
Pattern matches too muchGreedy quantifier (e.g. .*)Use lazy .*? or a tighter class [^"]*
DeprecationWarning: invalid escape sequenceForgot r"..."Always use raw strings for patterns
re.error: nothing to repeat* or + at start, or after another quantifierEscape or fix the position
AttributeError: 'NoneType' object has no attribute 'group'Match returned NoneCheck the match first: if m := re.search(...): ...
Replacement injects \1 literallyrepl is a non-raw string with "\1"Use r"\1" in replacement
Hangs on adversarial inputCatastrophic backtrackingAvoid nested unbounded (a+)+; use atomic-style refactor

See Also

Practice this

on practicepython.in

Short exercises that run in your browser and tell you what your code actually did, not just whether a test passed.