iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Python re

Python regex with the re module: raw strings, compile, named groups, the seven flags, and the subtleties that bite.

Regex — Python

EXAMPLE
import re

# ===== Raw strings (always) =====
pattern = r'\d{4}-\d{2}-\d{2}'   # raw avoids Python's own escape rules

# ===== Functions =====
re.match(pattern, '2024-04-10')          # match at start
re.search(pattern, 'logged on 2024-04-10') # anywhere
re.fullmatch(pattern, '2024-04-10')       # entire string
re.findall(pattern, 'a 2024-04-10 b 2024-04-11')  # list of strings
re.finditer(pattern, '...')              # iter of Match objects

# ===== Named groups =====
m = re.match(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})', '2024-04-10')
m.group('year')        # '2024'
m.groupdict()          # {'year': '2024', 'month': '04', 'day': '10'}

# ===== Compile for reuse =====
DATE = re.compile(r'^\d{4}-\d{2}-\d{2}$')
DATE.match('2024-04-10')        # faster on hot paths

# ===== Substitution =====
re.sub(r'\s+', ' ', 'a  b   c').strip()     # 'a b c'
re.sub(r'(?P<y>\d{4})-(\d{2})-(\d{2})', r'\3/\2/\g<y>', '2024-04-10')
# '10/04/2024'

# With a function:
re.sub(r'\$(\d+)', lambda m: f'AUD {int(m.group(1)):,}', 'Spent $1000 and $25000')

# ===== Flags =====
# re.IGNORECASE  re.I
# re.MULTILINE   re.M  (^ and $ match per line)
# re.DOTALL      re.S  (. matches newline)
# re.VERBOSE     re.X  (free-spacing + comments)
# re.UNICODE     re.U  (default in Python 3)
# re.ASCII       re.A  (force \w to ASCII only)

pattern = re.compile(r'''
    ^
    (?P<num>\d+)         # the integer part
    (?:\.(?P<frac>\d+))? # optional fractional part
    $
''', re.VERBOSE)

# ===== Lookarounds =====
re.search(r'(?<=\$)\d+', 'price $49')       # ['49']
re.findall(r'\d+(?= dollars)', '10 dollars; 5 cents')  # ['10']
re.findall(r'(?<!no )spam', 'spam, no spam')  # ['spam'] (only the first)

# ===== Splitting =====
re.split(r'[\s,]+', 'a b, c,d')   # ['a', 'b', 'c', 'd']

# ===== Unicode classes =====
re.findall(r'\p{L}+', 'abc 中文', re.U)
# WARNING: stdlib re does not support \p{}; use the third-party 'regex' module:
# pip install regex
import regex as re2
re2.findall(r'\p{L}+', 'abc 中文')

# ===== Patterns to internalise =====
# - Raw strings for every pattern
# - re.compile in hot loops
# - Named groups when >2 captures
# - re.VERBOSE for any non-trivial pattern
# - Use the 'regex' module for Unicode property classes + advanced features

# ===== Pitfalls =====
# - Forgetting r'' -> backslashes turn into other characters
# - re.search vs re.match (match only at start)
# - greedy quantifiers across newlines without re.S
# - Catastrophic backtracking from user input (^(a+)+$)
# - \b across Unicode in stdlib re is not Unicode-aware unless re.UNICODE

Why it matters

Python regex is concise once raw strings and re.compile become reflexes. Named groups + re.VERBOSE turn long patterns into readable ones; the regex module unlocks Unicode property classes. The biggest trap is re.match (start only) when you wanted re.search (anywhere).

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
import re
m = re.search(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})', '2026-06-07')
print(m.group('year'), m.group('month'), m.group('day'))
Try it Yourself »

Discussion

Loading…