re Module
Python re Module — The Complete Guide
Master regular expressions in Python: pattern matching, searching, extracting, and replacing text using the built-in re module.
Introduction
The re module is Python's built-in library for working with regular expressions (regex) — a powerful,
compact language for describing patterns in text. With re you can search for patterns, validate input (emails, phone
numbers), extract specific pieces of data, split strings intelligently, and perform advanced find-and-replace operations that would be
tedious or impossible with ordinary string methods.
re module lets you describe a pattern once and then find, validate, extract, or replace matching text anywhere.
Real-World Analogy
The Search Warrant
A regular expression is like a detailed description handed to a search team: "find anyone wearing a red hat and glasses." The team (the regex engine) scans the crowd (your text) and returns everyone who fits. You describe the pattern once, and it finds every match for you.
Prerequisites
Before You Start
- Python 3.x installed
- Basic understanding of strings and string methods
- The module is built in — just
import re(no installation needed) - A text editor or interactive shell to test patterns
- Optional: an online regex tester (like regex101) to visualize matches
Getting Started
Import the module and run your first pattern search.
import re
text = "My email is rumman@example.com"
match = re.search(r"\w+@\w+\.\w+", text)
if match:
print("Found:", match.group()) # Found: rumman@example.com
r"...") for patterns so backslashes like \w and \d are not misinterpreted.
Core Functions of re
re.search()
Find the first match anywhere in the string.
Returns a match object if the pattern is found (anywhere), or None otherwise.
re.match()
Match only at the beginning of the string.
Returns a match object only if the pattern matches starting at index 0.
re.findall()
Return all non-overlapping matches.
Gives back a list of every matching substring (or tuples if groups are used).
Essential re Functions
| Function | Purpose | Returns |
|---|---|---|
re.search(p, s) |
First match anywhere in the string | Match object or None |
re.match(p, s) |
Match at the start of the string | Match object or None |
re.fullmatch(p, s) |
Match the entire string | Match object or None |
re.findall(p, s) |
All matches as a list | List of strings/tuples |
re.finditer(p, s) |
All matches as an iterator | Iterator of match objects |
re.sub(p, r, s) |
Replace matches with replacement text | New string |
re.split(p, s) |
Split string by the pattern | List of strings |
re.compile(p) |
Pre-compile a pattern for reuse | Pattern object |
Common Metacharacters & Tokens
| Token | Meaning | Example |
|---|---|---|
. |
Any character except newline | a.c matches "abc", "axc" |
\d |
Any digit (0-9) | \d\d matches "42" |
\w |
Word character (letter, digit, _) | \w+ matches "hello_1" |
\s |
Whitespace (space, tab, newline) | a\sb matches "a b" |
^ |
Start of string / line | ^Hello |
$ |
End of string / line | end$ |
* |
0 or more of the previous | ab* matches "a", "abbb" |
+ |
1 or more of the previous | \d+ matches "123" |
? |
0 or 1 (optional) | colou?r matches "color"/"colour" |
{n,m} |
Between n and m repetitions | \d{2,4} |
[...] |
Character set | [aeiou] matches a vowel |
| |
OR (alternation) | cat|dog |
() |
Capturing group | (\d{4})-(\d{2}) |
Practical Examples
Extract all numbers with findall
import re
text = "Order 42 shipped, 7 pending, 128 total"
numbers = re.findall(r"\d+", text)
print(numbers) # ['42', '7', '128']
Capturing groups
import re
date = "2026-08-16"
m = re.search(r"(\d{4})-(\d{2})-(\d{2})", date)
print(m.group(0)) # 2026-08-16 (whole match)
print(m.group(1)) # 2026 (year)
print(m.group(2)) # 08 (month)
print(m.group(3)) # 16 (day)
Named groups
import re
m = re.search(r"(?P<year>\d{4})-(?P<month>\d{2})", "2026-08")
print(m.group("year")) # 2026
print(m.group("month")) # 08
Replace with re.sub
import re
text = "Call me at 123-456-7890 or 987-654-3210"
masked = re.sub(r"\d", "*", text)
print(masked) # Call me at ***-***-**** or ***-***-****
Split on multiple delimiters
import re
data = "apple, banana;cherry orange"
parts = re.split(r"[,;\s]+", data)
print(parts) # ['apple', 'banana', 'cherry', 'orange']
Compiling Patterns for Reuse
If you use a pattern many times, re.compile() pre-compiles it for better performance and cleaner code.
import re
# Compile once
email_pattern = re.compile(r"\w+@\w+\.\w+")
emails = ["a@x.com", "invalid", "b@y.org"]
for e in emails:
if email_pattern.fullmatch(e):
print(e, "is valid")
Useful Flags
| Flag | Effect |
|---|---|
re.IGNORECASE / re.I |
Case-insensitive matching |
re.MULTILINE / re.M |
^ and $ match at each line |
re.DOTALL / re.S |
. also matches newlines |
re.VERBOSE / re.X |
Allow whitespace and comments in patterns |
import re
text = "Hello WORLD"
print(re.findall(r"world", text, re.IGNORECASE)) # ['WORLD']
A Note on Performance
A well-written regex runs in roughly linear time \(O(n)\) over input length \(n\). But catastrophic backtracking from
nested quantifiers (like (a+)+) can explode to exponential time:
\[ T_{\text{worst}} = O(2^{n}) \]
Avoid ambiguous nested quantifiers on untrusted input to prevent this "ReDoS" pitfall.
Best Practices
Do This
- Always use raw strings
r"..."for patterns - Compile patterns you reuse with
re.compile() - Use named groups
(?P<name>...)for readability - Prefer specific tokens over greedy
.*where possible - Test complex patterns on sample data before deploying
- Avoid nested quantifiers on untrusted input (ReDoS risk)
Common Mistakes
re.search("\d+", s) — the \d may be misread and cause warnings.
re.search(r"\d+", s).
re.match expecting it to find a pattern anywhere — it only matches at the start of the string.
re.search to find a pattern anywhere in the string.
Interview Questions
| Question | Short Answer |
|---|---|
Difference between search and match? |
match checks only the start; search scans the whole string. |
What does findall return? |
A list of all non-overlapping matches (tuples if there are groups). |
| Why use raw strings for patterns? | To stop Python from interpreting backslashes before regex sees them. |
| What is a capturing group? | Parentheses () that capture part of a match for later retrieval. |
| What is catastrophic backtracking? | Exponential slowdown from ambiguous nested quantifiers — a ReDoS risk. |
Quick Revision
| Goal | Function |
|---|---|
| Find first match anywhere | re.search() |
| Get all matches | re.findall() |
| Replace text | re.sub() |
| Split by pattern | re.split() |
| Validate whole string | re.fullmatch() |
Key Takeaways
The re module gives Python powerful pattern matching for searching, extracting, validating, and
replacing text. Use raw strings, pick search vs match correctly, leverage groups and flags,
and compile reused patterns — while avoiding catastrophic backtracking.