Learn regex fundamentals with BaseHalf and AI
We opened the real regex-fundamentals folder in BaseHalf, laid literal, class, anchor, and escaping notes out as cards, wrote upstream into the practice note, and had Claude Code in the Agent Area grade ^[0-9]{5}$ as correct.
A short regex is easier to check when each piece lives on its own card and an agent can see both the cards and the practice note. We made an ordinary Desktop folder, dropped six short Markdown notes into it, and opened that folder in BaseHalf. The window title became regex-fundamentals. The sidebar listed every file. Each note became a card. We started Claude Code in the Agent Area on the right, with the practice card selected.
The folder on disk was Desktop/basehalf-learn-sessions/regex-fundamentals/. These were the files on the canvas:
regex-fundamentals/
00-goal.md
01-literals-and-classes.md
02-anchors-and-quantifiers.md
03-escaping.md
04-practice.md
sources.md
What each card held
00-goal.md set the boundary: read a pattern as literals, a class, anchors, and a quantifier, then check one practice match.
01-literals-and-classes.md pinned cat as three characters in order, [abc] as one of those letters, [0-9] as a digit, and, in JavaScript, . as any character except a line break unless the s flag is set.
02-anchors-and-quantifiers.md kept ^ as the start of the string, $ as the end, ? * +, {5} as exactly five, and {2,4} as two to four.
03-escaping.md noted that a special character matches as itself with a backslash in front: \. is a dot, \? is a question mark, \\ is a backslash.
sources.md linked the MDN Regular expressions guide, the cheatsheet, and Assertions. Those pages were the source of truth for the folder, not the model.
Upstream on the practice note
We connected the practice note to the three concept cards and to sources.md. On the canvas, lines from 01-literals-and-classes, 02-anchors-and-quantifiers, 03-escaping, and sources run into 04-practice. After that, 04-practice.md began with:
upstream:
- 01-literals-and-classes.md
- 02-anchors-and-quantifiers.md
- 03-escaping.md
- sources.mdThat list sticks in the file. Selection does not: it lives in .bh/cache/selection.yaml only while BaseHalf is open. We selected the practice card, and the status bar showed 04-practice, before asking Claude Code to grade it.
The ZIP practice
The practice card asked: write a pattern that matches a whole string only when it is a 5-digit ZIP code, and rejects 4 digits, 6 digits, and digits with extra characters.
Our tests on the card: 90210 should match; 9021, 902101, a90210, and 90210a should not.
Our answer: ^[0-9]{5}$. We used [0-9] from the class card and {5}, ^, and $ from the anchors card, so the pattern cannot leak into a longer string.
![regex-fundamentals canvas plus Agent Area: Claude Code grades ^[0-9]5$ as correct with full marks, checks each part against the upstream cards and the MDN cheatsheet, and says it ran the check in Node without editing files.](/_next/static/media/learn-regex-agent.bfab3069.webp)
What Claude Code actually said
Treat the reply as a draft. In this session Claude Code (Opus 4.5) said the grade was correct, and that ^[0-9]{5}$ got full marks. It checked the answer against the upstream cards, the three MDN pages in sources.md, and by running the pattern in Node. It did not edit any files.
It walked each part back to a card and a docs line: ^ to "start of the string" on card 02 and MDN's "beginning of input"; [0-9] to "a digit" on card 01; {5} to "exactly five" on card 02; $ to "end of the string" on card 02.
It also ran our five tests with /^[0-9]{5}$/.test(...) in Node, and all five gave the result we expected. It tried a few extra cases, including an empty string and strings with a line break, and the pattern rejected them.
![The same Claude Code session, scrolled to the tests: all five ZIP cases passed in Node, plus a note that with the m flag ^ and $ also match at a line break, so /^[0-9]5$/m can match 90210 followed by another line.](/_next/static/media/learn-regex-agent-tests.9e1da489.webp)
One note, not a deduction: the answer is only fully correct with no flags. With the m (multiline) flag, ^ and $ also match at a line break, so /^[0-9]{5}$/m can match 90210 followed by another line. Claude Code checked that in Node. Leave m off for a whole-string check.
It also noted that the MDN cheatsheet lists \d as equivalent to [0-9], so ^\d{5}$ is the same pattern. We kept [0-9], because that is what the class card teaches.
When the agent disagrees with the links in sources.md, keep the docs and fix the note on the canvas.
Same product, a real practice path
BaseHalf did not invent a regex tutor for us. We opened a Desktop folder, arranged ordinary Markdown, wrote upstream into the practice file, and let Claude Code grade from those files and the linked MDN pages. Card places stay under .bh/; the connections that matter stay in the files. This post is written from that session on the regex-fundamentals canvas, not from a fictional syllabus tree.