Source file src/internal/lazyregexp/lazyre.go

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package lazyregexp is a thin wrapper over regexp, allowing the use of global
     6  // regexp variables without forcing them to be compiled at init.
     7  package lazyregexp
     8  
     9  import (
    10  	"os"
    11  	"regexp"
    12  	"strings"
    13  	"sync"
    14  )
    15  
    16  // Regexp is a wrapper around regexp.Regexp, where the underlying regexp will be
    17  // compiled the first time it is needed.
    18  type Regexp struct {
    19  	str  string
    20  	once sync.Once
    21  	rx   *regexp.Regexp
    22  }
    23  
    24  func (r *Regexp) re() *regexp.Regexp {
    25  	r.once.Do(r.build)
    26  	return r.rx
    27  }
    28  
    29  func (r *Regexp) build() {
    30  	r.rx = regexp.MustCompile(r.str)
    31  	r.str = ""
    32  }
    33  
    34  func (r *Regexp) FindSubmatch(s []byte) [][]byte {
    35  	return r.re().FindSubmatch(s)
    36  }
    37  
    38  func (r *Regexp) FindStringSubmatch(s string) []string {
    39  	return r.re().FindStringSubmatch(s)
    40  }
    41  
    42  func (r *Regexp) FindStringSubmatchIndex(s string) []int {
    43  	return r.re().FindStringSubmatchIndex(s)
    44  }
    45  
    46  func (r *Regexp) ReplaceAllString(src, repl string) string {
    47  	return r.re().ReplaceAllString(src, repl)
    48  }
    49  
    50  func (r *Regexp) FindString(s string) string {
    51  	return r.re().FindString(s)
    52  }
    53  
    54  func (r *Regexp) FindAllString(s string, n int) []string {
    55  	return r.re().FindAllString(s, n)
    56  }
    57  
    58  func (r *Regexp) MatchString(s string) bool {
    59  	return r.re().MatchString(s)
    60  }
    61  
    62  func (r *Regexp) SubexpNames() []string {
    63  	return r.re().SubexpNames()
    64  }
    65  
    66  var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test")
    67  
    68  // New creates a new lazy regexp, delaying the compiling work until it is first
    69  // needed. If the code is being run as part of tests, the regexp compiling will
    70  // happen immediately.
    71  func New(str string) *Regexp {
    72  	lr := &Regexp{str: str}
    73  	if inTest {
    74  		// In tests, always compile the regexps early.
    75  		lr.re()
    76  	}
    77  	return lr
    78  }
    79  

View as plain text