Reading — step 1 of 5
Read
~1 min readProduction Features
Putting It All Together
You've built every layer:
| Layer | Built in lesson |
|---|---|
| Literal match | 1 |
| Metacharacters | 2 |
| Char classes | 3 |
| Quantifiers | 4 |
| Anchors | 5 |
| Alternation | 6 |
| NFA construction | 7 |
| NFA simulation | 8 |
| Quantifier NFA | 9 |
| Captures | 10 |
| findall + split | 11 |
What separates a toy from re2 / Go's regexp:
- DFA cache: convert subsets of NFA states into DFA states on the fly. Cache the transitions. After the first run over each input pattern, subsequent runs are constant work per character.
- Unicode:
\dshould match Devanagari digits,\wshould match Greek letters. Real engines have Unicode tables. - Encoding: UTF-8 byte-level matching is faster than per-codepoint. RE2 operates on bytes; results are reported as byte offsets.
- Compile-time validation: catch unbalanced parens, invalid backref numbers, character class boundary errors with good error messages.
- Lookarounds:
(?=...)(positive lookahead) and(?!...)(negative) let you assert without consuming. Hard in pure NFA — most engines fall back to backtracking for these.
What you've built handles:
- Most useful regex patterns
- Linear time (no catastrophic backtracking)
- Captures
- Real-world readability (your code matches Thompson's 1968 paper)
You now understand what powers grep, sed, awk, vim, perl, and almost every other tool that needs to find patterns in text.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…