CHAPTER 31 · INTERMEDIATE4 min read

Regular Expressions

Use text patterns for focused extraction and validation while keeping complexity and input boundaries under control.

Python 3.12+Free to readModule 7 of 13
YOUR NEXT SMALL WINS

By the end, you’ll be able to…

  • Choose search, fullmatch, and finditer intentionally.
  • Extract named groups from a readable pattern.
  • Avoid unnecessary regex and ambiguous repetition.

01Start with the text task

Regular expressions describe patterns in text. They work well for finding a ticket code inside a message or recognizing a simple, documented record format. They are less appropriate when a dedicated parser already understands the format: use json for JSON, csv for CSV, and ordinary string methods for a fixed prefix or delimiter.

Before writing a pattern, decide whether you need to find a substring, validate the entire input, or extract all matches. re.search finds the first match anywhere, re.fullmatch requires the entire string to fit, and re.finditer yields match objects in sequence. Confusing these operations can accept trailing junk in a supposed validator.

ticket_codes.py🐍Python
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

02Separate Python string escaping from pattern syntax

A regex pattern is first a Python string and then input to the regex engine. Raw strings such as r"\d+" prevent Python from interpreting most backslash escapes, making patterns easier to read. Raw strings do not turn off regex syntax: the regex engine still interprets its own backslashes and metacharacters.

Use [0-9] when a specification explicitly means ASCII digits. In a Unicode string pattern, \d also recognizes other Unicode decimal digits. Use re.escape when inserting literal user text into a pattern so punctuation such as . or + is not interpreted as an instruction. Never interpolate arbitrary text and assume it is literal.

literal_search.py🐍Python
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

03Named groups make extraction readable

Parentheses capture matched content. Named groups such as (?P<name>...) let your code use meaningful field names instead of remembering numeric group positions. Check whether a match exists before accessing its groups; None means the pattern did not match.

Regex recognition is only one validation stage. A date-like pattern can establish four digits, a hyphen, two digits, another hyphen, and two digits, yet still accept an impossible calendar date. Pass extracted values to a suitable domain parser or explicit checks rather than expanding one pattern into an unreadable substitute for application logic.

extract_record.py🐍Python
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

04Keep patterns bounded and reviewable

Greedy quantifiers try to consume as much text as possible while still allowing the match to succeed. Adding ? can make a quantifier reluctant, but this does not make arbitrary parsing safe or efficient. Prefer an explicit character class such as [^,]+ for a comma-free field over a vague .* when the format gives you a boundary.

Ambiguous nested repetition can cause extreme backtracking on unfortunate inputs. Keep untrusted input lengths bounded, avoid patterns such as repeated groups that can consume the same text in many ways, and test near-miss cases as well as successful matches. Compile reused patterns for a named, inspectable definition; readability matters more than compressing the expression into one clever line.

LET IT CLICK

The ideas worth keeping.

  • Choose the matching operation from the input contract.
  • Use raw patterns, named groups, and literal escaping deliberately.
  • Leave domain semantics to explicit checks or dedicated parsers.
TURN UNDERSTANDING INTO SOMETHING YOU CAN DO

Make it yours.

Type and test your code right here in the interactive workspace. Run your solution, check the output, and compare with the worked guide when ready.

01

Validate an internal record identifier

Accept exactly three uppercase ASCII letters, a hyphen, and four ASCII digits. Return True or False. Verify that a substring and trailing newline do not pass.

your_turn_1.py🐍Python
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.pyPython
import rerecord_id = re.compile(r"[A-Z]{3}-[0-9]{4}")def valid_id(text):    return record_id.fullmatch(text) is not Noneassert valid_id("ABC-0042")assert not valid_id("xABC-0042")assert not valid_id("ABC-0042\n")assert not valid_id("abc-0042")

fullmatch enforces the whole-input contract. Explicit ASCII ranges make the identifier alphabet unambiguous.

02

Extract duration fields

Parse a complete line such as read:25 using named groups. Return a name and positive integer minutes, rejecting zero.

your_turn_2.py🐍Python
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.pyPython
import repattern = re.compile(r"(?P<name>[a-z]+):(?P<minutes>[0-9]+)")def parse_duration(text):    match = pattern.fullmatch(text)    if match is None:        raise ValueError("expected lowercase-name:minutes")    minutes = int(match["minutes"])    if minutes <= 0:        raise ValueError("minutes must be positive")    return match["name"], minutesassert parse_duration("read:25") == ("read", 25)try:    parse_duration("read:0")except ValueError:    print("zero rejected")

The pattern checks structure and extracts fields. Numeric conversion and positivity remain readable application checks.

A SMALL QUESTION. A USEFUL NEXT STEP.

What stayed with you?

Check the ideas while they’re fresh. Your answers stay in this page and feedback appears as you go.

A LITTLE ACTIVE RECALL0 / 3 answered
01Which call best validates that the entire input is one ticket code?
02Why call re.escape on a literal label inserted into a pattern?
03A pattern accepts 2026-02-31 as YYYY-MM-DD. What should the program do next?
⚡CODING CHALLENGE
🔒Required to Mark Lesson Complete

Validate an internal record identifier

Accept exactly three uppercase ASCII letters, a hyphen, and four ASCII digits. Return True or False. Verify that a substring and trailing newline do not pass.

EXPECTED OUTPUT
[Process exited with code 0 - No output]
challenge.pyPython 3
Ctrl + ↵
Execution Console
Click "Run & Verify" (or press Ctrl + Enter) to test your code against the challenge.

Keep exploring.

The official references behind this chapter, when you want a second angle or the full details.

One chapter closer.

Reading is a start. Trying it yourself makes the connection.

Solve the hands-on coding challenge in the knowledge section to verify your code and unlock chapter completion.