| // Copyright 2018 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Package lazyregexp is a thin wrapper over regexp, allowing the use of global |
| // regexp variables without forcing them to be compiled at init. |
| package lazyregexp |
| |
| import ( |
| "os" |
| "regexp" |
| "strings" |
| "sync" |
| ) |
| |
| // Regexp is a wrapper around regexp.Regexp, where the underlying regexp will be |
| // compiled the first time it is needed. |
| type Regexp struct { |
| str string |
| once sync.Once |
| rx *regexp.Regexp |
| } |
| |
| func (r *Regexp) re() *regexp.Regexp { |
| r.once.Do(r.build) |
| return r.rx |
| } |
| |
| func (r *Regexp) build() { |
| r.rx = regexp.MustCompile(r.str) |
| r.str = "" |
| } |
| |
| func (r *Regexp) FindSubmatch(s []byte) [][]byte { |
| return r.re().FindSubmatch(s) |
| } |
| |
| func (r *Regexp) FindStringSubmatch(s string) []string { |
| return r.re().FindStringSubmatch(s) |
| } |
| |
| func (r *Regexp) FindStringSubmatchIndex(s string) []int { |
| return r.re().FindStringSubmatchIndex(s) |
| } |
| |
| func (r *Regexp) ReplaceAllString(src, repl string) string { |
| return r.re().ReplaceAllString(src, repl) |
| } |
| |
| func (r *Regexp) FindString(s string) string { |
| return r.re().FindString(s) |
| } |
| |
| func (r *Regexp) FindAllString(s string, n int) []string { |
| return r.re().FindAllString(s, n) |
| } |
| |
| func (r *Regexp) MatchString(s string) bool { |
| return r.re().MatchString(s) |
| } |
| |
| func (r *Regexp) SubexpNames() []string { |
| return r.re().SubexpNames() |
| } |
| |
| var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test") |
| |
| // New creates a new lazy regexp, delaying the compiling work until it is first |
| // needed. If the code is being run as part of tests, the regexp compiling will |
| // happen immediately. |
| func New(str string) *Regexp { |
| lr := &Regexp{str: str} |
| if inTest { |
| // In tests, always compile the regexps early. |
| lr.re() |
| } |
| return lr |
| } |