A Regex Builder for Go
I hate regular expressions:
- Regex syntax is ugly and often visually hard to parse.
- Regex metacharacters often need escaping in a way that quickly gets confusing and verbose.
- Regex syntax and features annoyingly diverge across different languages and libraries.
- Regex terminology and concepts can be confusing, e.g. “grouping”, “capturing”, and “lookaround”.
One side project that’s been on my backlog forever, then, is a regex builder library. The idea is to trade away the excessive concision of regexes for better clarity while also potentially rethinking some pattern matching concepts.
Oddly, there seem to be hardly any regex builder libraries for Go. The only one I’ve found even in the ballpark of what I’m aiming for is rex, but I find it lacking in a few ways:
- Rex is too interested in closely mirroring the concepts and terminology of regular expressions. I want something that casts off that baggage.
- Patterns should be composable: having defined a pattern, you should be able to use it as an element of another pattern.
Note
Composibility is actually something Ben Visness briefly experimented with in Python, though I think his solution still leans too much on conventional regex syntax.
Anyway, here’s what I’ve come up with: a Go library very unimaginatively called regex-builder.
A few warnings:
- The non-test code is ~1000 SLOC, mostly written by Opus 4.7. (My manual contribution was mainly playing around with API concepts until I hit on something that seemed simple and explicit but not execessively verbose.)
- The API surely is missing some needed features and conveniences.
- The API design tries not to lean too hard on Go-specific features, but a port to some other languages would require some rethinking.
- Performance for many cases currently seems to be about 2-3x slower than the equivalent regexes. I doubt this approach is inherently slower than regexes (at least for patterns that stick to regex functionality), but I’ve not yet attempted to narrow down where the bottlenecks are.
So consider this an idea being thrown over a wall rather than a polished product. That said, I decided to share this because the design already seems promising. I intend to try using this going forward, and hopefully over time that will expose gaps and lead to improvements.