lazyre.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. // Package lazyregexp is a thin wrapper over regexp, allowing the use of global
  5. // regexp variables without forcing them to be compiled at init.
  6. package lazyregexp
  7. import (
  8. "regexp"
  9. "sync"
  10. "gogs.io/gogs/internal/testutil"
  11. )
  12. // Regexp is a wrapper around regexp.Regexp, where the underlying regexp will be
  13. // compiled the first time it is needed.
  14. type Regexp struct {
  15. str string
  16. once sync.Once
  17. rx *regexp.Regexp
  18. }
  19. func (r *Regexp) Regexp() *regexp.Regexp {
  20. r.once.Do(r.build)
  21. return r.rx
  22. }
  23. func (r *Regexp) build() {
  24. r.rx = regexp.MustCompile(r.str)
  25. r.str = ""
  26. }
  27. func (r *Regexp) Find(b []byte) []byte {
  28. return r.Regexp().Find(b)
  29. }
  30. func (r *Regexp) FindSubmatch(s []byte) [][]byte {
  31. return r.Regexp().FindSubmatch(s)
  32. }
  33. func (r *Regexp) FindStringSubmatch(s string) []string {
  34. return r.Regexp().FindStringSubmatch(s)
  35. }
  36. func (r *Regexp) FindStringSubmatchIndex(s string) []int {
  37. return r.Regexp().FindStringSubmatchIndex(s)
  38. }
  39. func (r *Regexp) ReplaceAllString(src, repl string) string {
  40. return r.Regexp().ReplaceAllString(src, repl)
  41. }
  42. func (r *Regexp) FindString(s string) string {
  43. return r.Regexp().FindString(s)
  44. }
  45. func (r *Regexp) FindAll(b []byte, n int) [][]byte {
  46. return r.Regexp().FindAll(b, n)
  47. }
  48. func (r *Regexp) FindAllString(s string, n int) []string {
  49. return r.Regexp().FindAllString(s, n)
  50. }
  51. func (r *Regexp) MatchString(s string) bool {
  52. return r.Regexp().MatchString(s)
  53. }
  54. func (r *Regexp) SubexpNames() []string {
  55. return r.Regexp().SubexpNames()
  56. }
  57. func (r *Regexp) FindAllStringSubmatch(s string, n int) [][]string {
  58. return r.Regexp().FindAllStringSubmatch(s, n)
  59. }
  60. func (r *Regexp) Split(s string, n int) []string {
  61. return r.Regexp().Split(s, n)
  62. }
  63. func (r *Regexp) ReplaceAllLiteralString(src, repl string) string {
  64. return r.Regexp().ReplaceAllLiteralString(src, repl)
  65. }
  66. func (r *Regexp) FindAllIndex(b []byte, n int) [][]int {
  67. return r.Regexp().FindAllIndex(b, n)
  68. }
  69. func (r *Regexp) Match(b []byte) bool {
  70. return r.Regexp().Match(b)
  71. }
  72. func (r *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
  73. return r.Regexp().ReplaceAllStringFunc(src, repl)
  74. }
  75. func (r *Regexp) ReplaceAll(src, repl []byte) []byte {
  76. return r.Regexp().ReplaceAll(src, repl)
  77. }
  78. // New creates a new lazy regexp, delaying the compiling work until it is first
  79. // needed. If the code is being run as part of tests, the regexp compiling will
  80. // happen immediately.
  81. func New(str string) *Regexp {
  82. lr := &Regexp{str: str}
  83. if testutil.InTest {
  84. // In tests, always compile the regexps early.
  85. lr.Regexp()
  86. }
  87. return lr
  88. }