Regular Expressions Checkpoint
25 min · Intermediate
Need help? Ask a tutor on WhatsApp (opens in a new tab)Fix the mistakes
The slips that cost marks in this module. Spot each one, then check the fix.
A real task combines several ideas: a pattern, groups, the right function and a safe check. This checkpoint builds a small log parser and then tests your choices.
Build the pattern in small steps
Start with one part of the line, test it, then add the next. A log line has a date, a level and a message. Write one named group for each, and join them with the literal spaces between.
import re
LINE = re.compile(r"(?P<date>\d{4}-\d{2}-\d{2}) (?P<level>[A-Z]+) (?P<msg>.+)")print(LINE.fullmatch("2026-11-08 ERROR disk full").groupdict())Example 1 · Parse log lines into dictionaries
import re
LINE = re.compile(r"(?P<date>\d{4}-\d{2}-\d{2}) (?P<level>[A-Z]+) (?P<msg>.+)")lines = ["2026-11-08 ERROR disk full", "bad line", "2026-11-09 INFO backup done"]for line in lines: m = LINE.fullmatch(line) if m: print(m["level"], "->", m["msg"]) else: print("skipped:", line)ERROR -> disk full skipped: bad line INFO -> backup done
What this code does
- The compiled pattern is named once and reused.
- The
if m:guard handles a line that does not fit.
groupdict() returns the named groups as a dictionary, ready to use.
Pick the function for the job
To check a value use fullmatch. To pull one thing from a line use search. For every hit use findall or finditer. To change text use sub. Match the function to the question.
Example 2 · Clean and count with sub and finditer
import re
raw = "Call 98765-43210 or 11111-22222 today"clean = re.sub(r"\s+", " ", raw)print(clean)phones = [m.group() for m in re.finditer(r"\d{5}-\d{5}", clean)]print(phones)print(re.sub(r"\d{5}-(\d{5})", r"#####-\1", clean))Call 98765-43210 or 11111-22222 today ['98765-43210', '11111-22222'] Call #####-43210 or #####-22222 today
What this code does
subfixes the spacing first.finditercollects each phone number.- A group keeps the last five digits while hiding the rest.
Before you ship a pattern
Check these. Is it a raw string? Are quantifiers greedy where they should be lazy? Does user text go through re.escape? Is a None result handled? Would a plain string method or a parser do the job better?
Example 3 · Validate and escape
import re
term = "a+b"print(bool(re.search(term, "a+b")))print(bool(re.search(re.escape(term), "a+b")))print(bool(re.fullmatch(r"[1-9]\d{5}", "560001")))False True True
What this code does
- Unescaped,
a+bmeans one or moreathenb, so it fails on the texta+b. - The escaped pattern finds the plus sign, and
fullmatchaccepts a PIN code.
Finish up
Mark complete & continue
Next: date, datetime and timedelta