Chapter 17 of 21
Datetime & Temporal Arithmetic
Current Study Module
Regular Expressions (re)
Testing with pytest & TDD
Chapter 16 • Pattern Processing

Regular Expressions (re Module)

Regular expressions are powerful mini-programs used for string validation, parsing, and extraction. Learn why Python requires raw string literals (r"..."), understand the critical differences between re.search(), re.match(), and re.findall(), and write clean, maintainable patterns using named capture groups and re.VERBOSE.

1. Why Raw Strings (r"...") Are Mandatory

Both standard Python string literals and regular expressions use the backslash character (\) for escape sequences (like \n or \t). Without a raw string, matching a literal backslash requires four backslashes (\\\\)!

The Golden Rule: Always prefix regular expression patterns with r (e.g. r"\d3-\d4") so Python disables its own string escape interpretation.

2. "re.match" vs "re.search" vs "re.findall"

FunctionScan BehaviorReturn Value
re.match(pattern, string)Matches only at the very beginning (index 0) of the string.Match object if start matches, else None.
re.search(pattern, string)Scans the entire string for the first occurrence.Match object for first match, else None.
re.findall(pattern, string)Scans the whole string for all non-overlapping occurrences.List of matching strings or tuples of groups.
re.sub(pattern, repl, string)Replaces matches with replacement string.Clean transformed string.
import re

log_line = "2026-10-15 [ERROR] user_id=4092 failed to authenticate on node-east"

# re.match fails if the pattern isn't at the very start:
print("re.match on [ERROR]:", re.match(r"[ERROR]", log_line))  # None!

# re.search scans through the text:
match = re.search(r"user_id=(d+)", log_line)
if match:
    print("Found User ID:", match.group(1))  # '4092'

3. Named Capture Groups for Clean Extraction

Instead of referencing capture groups by arbitrary numeric indices (group(1), group(2)), use (?P<name>...) to extract typed dictionary records:

# Complex log parsing with Named Capture Groups
pattern = r"(?P<date>d{4}-d{2}-d{2})s+[(?P<level>w+)]s+user_id=(?P<uid>d+)"

sample = "2026-10-15 [WARNING] user_id=8921 session expired"
m = re.search(pattern, sample)

if m:
    data = m.groupdict()
    print("Parsed Dictionary:", data)
    print("Extracted Level:", data["level"])  # 'WARNING'

4. Documenting Complex Regex with re.VERBOSE

Long regular expressions look like unreadable line noise. The re.VERBOSE flag allows you to spread patterns across multiple lines, ignore internal whitespace, and write explanatory comments:

# Self-documenting email validation regex using re.VERBOSE
email_pattern = re.compile(r"""
    ^                   # Beginning of string
    [a-zA-Z0-9_.+-]+    # Local username
    @                   # Mandatory @ separator
    [a-zA-Z0-9-]+       # Domain name
    .                  # Dot separator
    [a-zA-Z0-9-.]+$     # Top-level domain (TLD)
""", re.VERBOSE)

print("Valid email?", bool(email_pattern.match("support@hifitoolkit.com")))

Explore Related Tools

Hand-picked utilities and calculators related to this tool.

Related Tools