How to play
The board is a square grid, 2×2 to 5×5, as the label says (Level 10 of 12 · 5×5). Row clues sit on plaques to the left and column clues hang above, read top to bottom. Fill it so every row and column matches its clue.
Click a cell and type: the cursor moves right, then down a row. Arrows move, Backspace clears (stepping back from an empty cell), and Space clears and moves on. Clicking a clue jumps to the first empty cell of its line, and Clear the grid starts over.
A clue has to match its whole line: the game wraps it as ^(?:clue)$, so go+d across four cells can only be good. A clue turns green when its full line matches, and red as soon as no filling could match: an x under at goes red at once. The status line shows -- FILLING --, -- DEAD END -- or -- SOLVED --, the two clues through the current cell, and the clues right. Any filling that satisfies every clue wins, not only the intended one.
The score is hints. Ask the duck shows up to three questions per level, and each one counts: a solve with none earns gold, one silver, more bronze. The solved card offers Next level (or Enter), Clear and solve again and Copy share link, which copies a link to your levels solved and hints used.
What you’ll learn
Twelve levels, growing with the grid:
- 2×2: Plain letters, A choice of two. Clues that spell their line out, then classes like
[ou], where the crossing line picks the letter. - 3×3: Either or, Vowel work, Interlocked. Clues with two readings that a crossing settles, the vowel class
[aeiou], and cells that must satisfy two classed clues at once. - 4×4: One or more, Zero or more, Take it or leave it, Count on it.
+,*,?and{2}, where the line’s width decides how many times each repeats. - 5×5: Read it back, Two of a kind, The whole toolbox. Backreferences:
(.)(.)c\2\1is a palindrome,(.)\1a doubled letter,(..)\1a repeated pair, mixed with(an){2}and classes.
Regex Trainer drills writing patterns; this game drills reading them. You work out exactly which strings a pattern accepts, how a fixed length pins a quantifier’s count, and that a backreference repeats the text a group caught, not its pattern.
Good to know
- It runs your browser’s JavaScript engine. Each clue becomes
new RegExp('^(?:' + clue + ')$')with no flags, a full match on the line. regexcrossword.com anchors its clues the same way. - Every level is proven solvable: a gate runs each level’s own grid through the judge, 39 fixtures check full, partial, one-letter-off and rejected grids, and a browser test plays the first two levels from the keyboard.
- Progress stays in your browser: the fewest hints per level, in
localStorage, and the game reopens at your first unsolved level. A half-filled grid isn’t saved. - Not covered yet: alternation (Either or teaches with classes; no clue contains
|), anchors, negated classes like[^aeiou], ranges like[a-m],\dand\w, lookarounds, and grids past 5×5. Cells take letters only. - regexcrossword.com is the classic: 70 puzzles in 11 sets such as Tutorial, Double Cross and Hexagonal, plus player-made puzzles and a builder, and a line there can carry two clues. This game is smaller and gentler: 12 grids, one new feature per level, and the duck’s questions when you’re stuck.
Questions
How do you solve a regex crossword?
Start with the clues that leave no choice, such as a spelled-out word or a quantifier whose count the line’s length fixes. Then work cell by cell: each cell’s letter has to fit its row clue and its column clue, so take what both allow. A backreference copies letters within a line, so one filled cell gives you its twin.
How do you read a regular expression?
Left to right, one token at a time, with each quantifier applying only to the token or group right before it: ha{3} repeats the a, (ha){3} the pair. Alternation binds loosest of all, which is the trap with anchors:
/^ab|cd$/.test('abx'); // true: ^ab, or cd$
/^(?:ab|cd)$/.test('abx'); // false
That’s why the game wraps each clue in (?:…) before anchoring it.
What does \1 mean in regex?
\1 matches the same text the first capturing group matched, not the same pattern. ^(.)\1$ accepts ee but not ef, while ^(.)(.)$ accepts both. Groups are numbered by their opening parentheses, so in (.)(.)c\2\1 the \2 repeats the second letter and \1 the first.
What’s the difference between *, + and ? in regex?
* means zero or more of the item before it, + one or more, and ? zero or one:
['bt', 'bot', 'boot'].map((s) => /^bo*t$/.test(s)); // [true, true, true]
['bt', 'bot', 'boot'].map((s) => /^bo+t$/.test(s)); // [false, true, true]
['bt', 'bot', 'boot'].map((s) => /^bo?t$/.test(s)); // [true, true, false]