Text Processing and Regular Expressions¶
By the end of this lesson you'll be able to:
- Write basic regular expressions to match patterns in text
- Use
re.search(),re.findall(),re.split(), andre.sub()to search and transform text - Build patterns using character classes, quantifiers, anchors, and groups
- Use raw strings (
r"...") to avoid backslash confusion
Regular expressions (regex) are a mini-language for describing text patterns. With a single regex, you can find phone numbers, validate email addresses, or extract data from thousands of lines of text.
Welcome to Chapter 29!
Regular expressions look scary at first — but once you learn the building blocks, they're incredibly powerful.
One line of regex can do what would take 20 lines of string methods.
Let's decode the mystery! Let's code it together!
The re Module¶
Import Python's regex module with import re.
The core functions are:
| Function | Returns | Use when |
|---|---|---|
re.search(pattern, text) |
Match object or None |
Check if pattern appears anywhere |
re.findall(pattern, text) |
List of all matches | Get every occurrence |
re.split(pattern, text) |
List of pieces | Split text by a pattern |
re.sub(pattern, replacement, text) |
New string | Replace matches |
Raw Strings¶
Regex patterns use backslashes a lot — \d, \w, \s.
In regular Python strings, \d is treated as a special escape sequence.
To avoid confusion, always write regex patterns as raw strings by putting r before the quote: r"\d".
1 2 3 4 5 | |
Rule: always use r"..." for regex patterns.
Basic Pattern Elements¶
Before we write real patterns, here are the building blocks:
| Pattern | Matches |
|---|---|
. |
Any single character (except newline) |
\d |
A digit (0–9) |
\w |
A word character (letter, digit, underscore) |
\s |
A whitespace character (space, tab, newline) |
\D |
Not a digit |
\W |
Not a word character |
\S |
Not whitespace |
^ |
Start of the string |
$ |
End of the string |
Quantifiers¶
Quantifiers control how many times a pattern element repeats:
| Quantifier | Meaning | Example |
|---|---|---|
* |
0 or more times | \d* — zero or more digits |
+ |
1 or more times | \d+ — one or more digits |
? |
0 or 1 times | \d? — optional digit |
{n} |
Exactly n times | \d{3} — exactly 3 digits |
{n,m} |
Between n and m times | \d{2,4} — 2 to 4 digits |
re.search() — Find First Match¶
re.search(pattern, text) scans through text looking for the first location where the pattern matches.
It returns a match object if found, or None if not.
What Do You Think Will Happen?
The code below searches for a phone number pattern in different strings.
Which strings do you think will match the pattern \d{3}-\d{4}?
Make your guess — then run it!
match.group() returns the text that was matched.
re.findall() — Find All Matches¶
re.findall(pattern, text) returns a list of every non-overlapping match.
See It: The Regex Match Lab¶
What Do You Think Will Happen?
The lab below starts with the pattern \d{3}-\d{4}. Read the chips under
the pattern box, then predict: which pieces of the sample text will
light up — and how many matches will findall report?
Explore the Regex Match Lab MicroSim
Now experiment: delete the - from the pattern and watch the matches change instantly. Try each preset button, then build your own pattern one character at a time. The chip strip always translates your pattern into plain English — regex stops being magic once you can read it aloud.
Character Classes¶
A character class is a set of characters in square brackets. It matches any single character in the set.
| Pattern | Matches |
|---|---|
[aeiou] |
Any lowercase vowel |
[A-Z] |
Any uppercase letter |
[a-z] |
Any lowercase letter |
[0-9] |
Any digit (same as \d) |
[^aeiou] |
Any character that is NOT a vowel |
re.split() — Split by Pattern¶
re.split(pattern, text) splits text wherever the pattern matches — like str.split() but with regex power.
re.sub() — Substitute Matches¶
re.sub(pattern, replacement, text) replaces every match with the replacement string.
1 2 3 4 5 6 7 8 9 | |
Anchors: Start and End¶
^ matches the start of the string.
$ matches the end.
1 2 3 4 5 6 7 | |
Alternation with |¶
| means "or" — match either the left or the right pattern.
1 2 3 4 5 | |
Groups with Parentheses¶
Parentheses () create a group — they let you capture specific parts of a match.
1 2 3 4 5 6 7 | |
Escaping Special Characters¶
Some characters have special meaning in regex: ., *, +, ?, (, ), [, ], {, }, ^, $, |, \.
To match them literally, escape them with a backslash: \. matches a literal dot.
1 2 3 | |
Compiled Regex Patterns¶
If you use the same pattern many times, compile it first for better performance:
1 2 3 4 5 6 | |
Learning Check¶
Your Turn — Extract Phone Numbers
The code below should extract all phone numbers from the text.
The pattern only matches 3-digit numbers. Fix the pattern to match the full format NNN-NNN-NNNN!
Experiments¶
Try these changes. Predict what will happen first, then run it to check!
-
Use
re.findall(r"\b\w{5}\b", text)to find all 5-letter words in a sentence.\bis a word boundary. You'll know it worked when you see only 5-letter words. -
Use
re.sub(r"\b\d+\b", "NUM", "I have 3 cats and 12 birds")to replace all numbers with "NUM". You'll know it worked when you see"I have NUM cats and NUM birds". -
Validate a password: at least 8 characters, at least one digit. Use
re.search(r"^.{8,}$", pw)andre.search(r"\d", pw). You'll know it worked when"abc12345"passes and"abc123"fails (too short). -
Use
re.split(r"\s*,\s*", "Alice , Bob, Carol, Dave")to split a comma-separated list ignoring extra spaces. You'll know it worked when you see four clean names. -
Compile the pattern
r"\d{4}"and use it to find all 4-digit years in a sentence about history. You'll know it worked when you see a list of years.
Regex Wizard!
Regular expressions are a superpower — one pattern can search through millions of lines of text!
They appear in web scraping, data validation, log analysis, and almost every text processing task.
You've just added a serious tool to your programmer toolbox. Let's keep coding!