regexp2

A feature-rich Go regex engine ported from .NET with backtracking, lookaround, and Perl-compatible syntax.

Library
Go
vv1.12.0
1,185stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
62/100Good
Development Activity72
Maintenance28
Community60
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
77/100Good
Architecture82
Code Quality85
Innovation75
Learning Curve65

regexp2 is a full-featured regular expression engine for Go, ported from the .NET framework’s System.Text.RegularExpressions.Regex engine. Unlike Go’s built-in regexp package, which guarantees linear-time matching via the RE2 algorithm but sacrifices expressive power, regexp2 supports backtracking, letting it handle complex patterns such as lookaheads, lookbehinds, backreferences, and possessive quantifiers that RE2 cannot express.

Version 2 modernizes the API surface with variadic compile options for performance tuning (bounded backtracking stacks, pooled rune buffers, cached replacement patterns), a regexp-compatible adapter package for drop-in migration, Split support, and Unicode 17.0.0-based character class and grapheme cluster matching. It targets Go 1.25 and is safe for concurrent use across goroutines.

What You Get

  • A Regexp type with Compile/MustCompile plus Match/FindStringMatch/FindNextMatch methods for full backtracking regex support in Go
  • A compat sub-package that mirrors the standard library’s regexp.Regexp method signatures (Find*, Match*) so it can be swapped in with minimal code changes
  • Configurable compile options for match timeouts, backtracking stack size limits, and pooled buffer/cache tuning to control memory and performance trade-offs
  • Unicode 17.0.0-based \p{...} character class support, including scripts, properties, property=value syntax, and \X extended grapheme cluster matching
  • Additional Perl/PCRE syntax such as \Q...\E literal quoting, \R newline sequences, and possessive quantifiers (*+, ++, ?+)

Common Use Cases

  • Porting regex patterns from a .NET codebase to Go without rewriting them for RE2 compatibility
  • Validating or extracting data with patterns that require lookahead/lookbehind or backreferences
  • Building code-generation tools (via the companion regexp2cg project) that compile hot-path regexes ahead of time
  • Wrapping regexp2 behind the compat.Matcher interface so libraries can accept either the standard regexp package or regexp2 interchangeably

Under The Hood

Architecture Compile parses a pattern via syntax.Parse into a tree (syntax/tree.go), then emits bytecode (syntax/code.go) through a writer, with optional optimization passes (syntax/optimizations.go, syntax/prefixanalyzer.go). At runtime, a Runner (runner.go) executes that bytecode as a backtracking virtual machine using explicit stacks rather than recursion, pooled through sync.Pool on Regexp.runnerPool for safe concurrent reuse. Regexp exposes hook points (findFirstChar, execute, executeQuick) so generated engines from the companion regexp2cg project can override the interpreter loop, and a separate boolean-only quickCode program supports fast existence checks. Parsing/syntax concerns stay cleanly separated from execution, and the compat package layers a standard-library-compatible facade on top without touching the core engine.

Tech Stack A pure Go module (github.com/dlclark/regexp2/v2, targeting Go 1.25) with no third-party dependencies — only standard library packages such as container/list, sort, sync, slices, and unicode/utf8. Originally ported from .NET’s System.Text.RegularExpressions.Regex, it ships its own helpers package with custom ASCII bitmap, index-of, and rune-buffer utilities to minimize allocations. CI runs on CircleCI across Linux (multiple architectures) and Windows via go test ./... on Go 1.25, and a Taskfile.yml drives benchmark-comparison tooling across git references.

Code Quality The test suite is extensive — dozens of _test.go files with hundreds of test functions covering ECMAScript compatibility, capture ordering, code generation, and corpus tests borrowed from the PCRE, RE2, and Rust regex test suites, plus dedicated build-tagged files (race_enabled_test.go/race_disabled_test.go) for race-detector-sensitive paths. Errors are explicit and typed (ErrBacktrackingStackLimit, structured parse errors) rather than silently swallowed, naming follows Go conventions, and public APIs carry doc comments throughout. No standalone linter config was found, but CI enforces tests across multiple platforms and architectures on every change.

API Design The public API closely mirrors Go’s standard regexp package (Compile/MustCompile, MatchString, FindStringMatch), keeping the learning curve low for developers already familiar with it, while the compat sub-package provides fully interface-compatible Find*/Match* methods so existing code can adopt regexp2 with a small import change. Variadic CompileOption functions let callers opt into stack-size and buffer-pool tuning without a sprawling configuration struct, and the README documents every default and trade-off in a table. One real ergonomic wrinkle: capture offsets are rune-based rather than byte-based by default (mitigated via ByteRange()), and because match methods return errors unlike the stdlib, the compat adapter has to panic on those error paths to preserve the standard-library method signatures.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search