Home/Learn/Python A–Z/Regular Expressions — the re Module

Regular Expressions — the re Module

Advanced
Stdlib Power Tools

search finds, findall collects, sub replaces, groups extract — with raw strings, character classes and quantifiers making Python a text-processing power tool.

Overview

Regex is a mini-language for describing text patterns — validation (emails, phone numbers), extraction (IDs from logs), and transformation (sub with backreferences). The re module API is small: search (first match anywhere), match (only at the start), findall (all matches), sub (replace), finditer (lazy match objects). Two habits prevent most regex pain: always write patterns as raw strings r"...", and reach for groups (...) to pull out the parts you actually want.

The Five Functions

Match objects hold .group() / .groups() / .start(). findall returns strings (or tuples if groups). Compile once when reusing a pattern in a loop.

search / findall / sub / finditer / match
import re

log = "2026-07-10 ERROR user=asha code=500; 2026-07-10 INFO user=ravi code=200"

# search — first occurrence anywhere
m = re.search(r"code=(\d+)", log)
print(m.group(0), m.group(1))          # code=500  500

# findall — everything, capture groups only
print(re.findall(r"user=(\w+)", log))  # ['asha', 'ravi']

# sub — replace (mask phone numbers)
txt = "call 9876543210 or 9123456789"
print(re.sub(r"\d{10}", "XXXXXXXXXX", txt))

# Named groups — self-documenting extraction
pat = re.compile(r"(?P<date>\d{4}-\d{2}-\d{2}) (?P<level>\w+)")
for m in pat.finditer(log):
    print(m["date"], m["level"])        # 2026-07-10 ERROR / INFO

# match vs search: match anchors at position 0
print(re.match(r"\d+", "abc123"))      # None
print(re.search(r"\d+", "abc123"))     # <re.Match ... '123'>

Pattern Vocabulary You Must Know

Classes (\d \w \s), quantifiers (* + ? {m,n}), anchors (^ $ \b), alternation (|), and the greedy-vs-lazy distinction (.* vs .*?) — enough for 90% of real patterns.

Validation, greedy vs lazy, boundaries
import re

# Indian mobile: optional +91, then 10 digits starting 6-9
mobile = re.compile(r"^(?:\+91[- ]?)?[6-9]\d{9}$")
print(bool(mobile.match("+91 98765 43210".replace(" ", ""))))  # True
print(bool(mobile.match("1234567890")))                        # False

# Simple email shape (real validation is looser — send a link!)
email = re.compile(r"^[\w.+-]+@[\w-]+\.[\w.]+$")
print(bool(email.match("asha.k+test@aicancode.org")))          # True

# Greedy vs lazy — the classic trap
html = "<b>bold</b> and <i>italic</i>"
print(re.findall(r"<(.*)>", html))     # ['b>bold</b> and <i>italic</i'] !!
print(re.findall(r"<(.*?)>", html))    # ['b', '/b', 'i', '/i']  — lazy

# Word boundaries — whole words only
print(re.sub(r"\bjava\b", "python", "java javascript java"))
# python javascript python  (javascript untouched)

# Split on multiple delimiters
print(re.split(r"[,;|]\s*", "a, b; c| d"))   # ['a','b','c','d']

Key Points to Remember

  • 1Always raw strings: r"\d+" — otherwise Python eats your backslashes
  • 2search anywhere vs match at start; findall returns group contents
  • 3.* is greedy (longest), .*? is lazy (shortest) — the #1 regex bug
  • 4Groups (...) extract; named groups (?P<name>...) document; \b bounds whole words

Interview Questions

Sign in to ask Aria
1

Difference between re.match and re.search?

EasyCapgemini
2

Write a regex for Indian mobile numbers with optional +91 prefix.

MediumPaytm
3

Explain greedy vs lazy quantifiers with the HTML-tag example.

HardAmazon

Ask Aria about Regular Expressions — the re Module

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…