feat: allow custom regexp engine via RegexpCompiler option
- Dominant language
- Go
- Stars
- 478
- Forks
- 37
- PR merge metrics
- No merged PRs in 30d
Description
**Is your feature request related to a problem? Please describe.**
The `doc.go` already acknowledges that Go's `regexp` package differs from ECMA 262 (no back-references, no lookahead/lookbehind). This is documented under "Deviations from the specification" with a link to the [regexp2 comparison table](https://github.com/dlclark/regexp2?tab=readme-ov-file#compare-regexp-and-regexp2).
Currently, there is no way to plug in an alternative regexp engine. Users working with schemas that use PCRE-specific features (e.g., `(?=...)` lookahead in `pattern` or `patternProperties`) cannot validate them correctly.
**Describe the solution you'd like**
Add a `RegexpCompiler` option to `ResolveOptions` that allows users to provide a custom regexp compiler. The default behavior remains unchanged (Go's `regexp.Compile`).
The proposed API:
```go
// A Regexp is a compiled regular expression.
type Regexp interface {
MatchString(s string) bool
}
// A RegexpCompiler compiles a regular expression pattern string into a Regexp.
type RegexpCompiler func(pattern string) (Regexp, error)
type ResolveOptions struct {
// ... existing fields ...
// RegexpCompiler compiles regular expression patterns used in "pattern" and
// "patternProperties" keywords. If nil, Go's regexp.Compile is used.
RegexpCompiler RegexpCompiler
}
```
Usage with `regexp2` (note: `regexp2.MatchString` returns `(bool, error)`, so an adapter is needed):
```go
import "github.com/dlclark/regexp2"
type regexp2Adapter struct {
re *regexp2.Regexp
}
func (r regexp2Adapter) MatchString(s string) bool {
ok, err := r.re.MatchString(s)
return err == nil && ok
}
compiler := func(pattern string) (jsonschema.Regexp, error) {
re, err := regexp2.Compile(pattern, regexp2.ECMAScript)
if err != nil {
return nil, err
}
return regexp2Adapter{re: re}, nil
}
resolved, err := schema.Resolve(&jsonschema.ResolveOptions{
RegexpCompiler: compiler,
})
```
**Implementation details**
- Minimal interface: `Regexp` requires only `MatchString(string) bool`, matching the existing validation path and avoiding changes to runtime validation semantics
- Internal `resolvedInfo` stores `Regexp` interface instead of `*regexp.Regexp`
- `validate.go` should require little or no change, since validation already only needs `MatchString` semantics
- `doc.go` "Deviations" section updated to mention the escape hatch
- Full test coverage: custom compiler for `pattern`, `patternProperties`, and error propagation
- Fully backwards-compatible — `nil` `RegexpCompiler` defaults to `regexp.Compile`
**PR:** https://github.com/google/jsonschema-go/pull/73
Contributor guide
Assessment
This issue has not been assessed yet.