Real-World Recipes
Patterns you'll actually use, each verified. Copy freely.
Log lines: extract the fields
2026-10-13 14:22:01 ERROR disk full on /dev/sda1
2026-10-13 14:23:44 INFO cleanup started
>>> log = "2026-10-13 14:22:01 ERROR disk full on /dev/sda1"
>>> m = re.search(r"(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) (\w+) (.*)", log)
>>> m.groups()
('2026-10-13', '14:22:01', 'ERROR', 'disk full on /dev/sda1')
Verified. Date, time, level, message — the (.*) at the end grabs
"the rest." Then filter:
>>> [l for l in logs if re.search(r"^.*\bERROR\b", l)] # error lines only
CSV-ish data: split carefully
>>> re.split(r"\s*,\s*", "a, b ,c")
['a', 'b', 'c'] # commas with optional surrounding spaces
Verified. (For real CSV with quoted commas, use Python's csv
module — that's the parser rule from chapter 1.)
Find all numbers, including decimals
>>> re.findall(r"\d+(?:\.\d+)?", "pi is 3.14, count 42")
['3.14', '42']
Verified. The (?:\.\d+)? is an optional decimal part — note the
escaped dot.
Dates: find them, then validate properly
>>> re.findall(r"\b\d{4}-\d{2}-\d{2}\b", "from 2026-10-13 to 2026-11-01")
['2026-10-13', '2026-11-01']
Verified. But \d{2} matches 99 — this finds date-shaped
text, including 2026-99-99. Finding with regex, validating
with real code:
from datetime import date
>>> date.fromisoformat("2026-10-13") # works
datetime.date(2026, 10, 13)
>>> date.fromisoformat("2026-99-99") # raises ValueError — not a date
Traceback (most recent call last):
ValueError: month must be in 1..12
The pattern narrows the haystack; the library judges. Same principle applies to emails (next section).
Email: the honest answer
There is no regex that perfectly validates email addresses — the
spec allows absurdities like " "@example.com. The pragmatic
approach:
>>> bool(re.fullmatch(r"[^@\s]+@[^@\s]+\.[^@\s]+", "paul@example.com"))
True
>>> bool(re.fullmatch(r"[^@\s]+@[^@\s]+\.[^@\s]+", "not-an-email"))
False
Verified. "Something @ something . something, no spaces" catches typos, which is all client-side validation should do. Real validation is sending the email and seeing if it arrives.
Renaming files: the shell one-liner
ls *.jpeg | sed -E 's/\.jpeg$/.jpg/' # preview the new names
sed -E 's/pattern/replacement/' — the s command substitutes.
Preview first (as shown), then loop to actually rename. (Bulk
renaming for real deserves a script with a dry run — see Bash
for Mere
Mortals.)
Validation vs. extraction (the mantra)
- Extraction:
re.search/findall, no anchors — find the pattern in the wild. - Validation:
re.fullmatchor^...$— the whole input must be the pattern.
Say which one you mean before you write the pattern. Half of regex confusion is answering the wrong question.
Next: Regex Flavors