github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zstring/regex.go (about) 1 package zstring 2 3 import ( 4 "regexp" 5 "sync" 6 "time" 7 ) 8 9 type regexMapStruct struct { 10 Value *regexp.Regexp 11 Time int64 12 sync.RWMutex 13 } 14 15 var ( 16 l sync.RWMutex 17 regexCache = map[string]*regexMapStruct{} 18 regexCacheTimeout uint = 1800 19 ) 20 21 func init() { 22 go func() { 23 ticker := time.NewTicker(600 * time.Second) 24 for range ticker.C { 25 clearRegexpCompile() 26 } 27 }() 28 } 29 30 // RegexMatch check for match 31 func RegexMatch(pattern string, str string) bool { 32 if r, err := getRegexpCompile(pattern); err == nil { 33 return r.Match(String2Bytes(str)) 34 } 35 return false 36 } 37 38 // RegexExtract extract matching text 39 func RegexExtract(pattern string, str string) ([]string, error) { 40 r, err := getRegexpCompile(pattern) 41 if err == nil { 42 return r.FindStringSubmatch(str), nil 43 } 44 return nil, err 45 } 46 47 // RegexExtractAll extract matching all text 48 func RegexExtractAll(pattern string, str string, count ...int) ([][]string, error) { 49 r, err := getRegexpCompile(pattern) 50 if err == nil { 51 n := -1 52 if len(count) > 0 { 53 n = count[0] 54 } 55 return r.FindAllStringSubmatch(str, n), nil 56 } 57 return nil, err 58 } 59 60 // RegexFind return matching position 61 func RegexFind(pattern string, str string, count int) [][]int { 62 if r, err := getRegexpCompile(pattern); err == nil { 63 return r.FindAllIndex(String2Bytes(str), count) 64 } 65 return [][]int{} 66 } 67 68 // RegexReplace replacing matches of the Regexp 69 func RegexReplace(pattern string, str, repl string) (string, error) { 70 r, err := getRegexpCompile(pattern) 71 if err == nil { 72 str = r.ReplaceAllString(str, repl) 73 } 74 return str, err 75 } 76 77 // RegexReplaceFunc replacing matches of the Regexp 78 func RegexReplaceFunc(pattern string, str string, repl func(string) string) (string, error) { 79 r, err := getRegexpCompile(pattern) 80 if err == nil { 81 str = r.ReplaceAllStringFunc(str, repl) 82 } 83 return str, err 84 } 85 86 // RegexSplit split the string 87 func RegexSplit(pattern string, str string) ([]string, error) { 88 r, err := getRegexpCompile(pattern) 89 var result []string 90 if err == nil { 91 result = r.Split(str, -1) 92 } 93 return result, err 94 } 95 96 func clearRegexpCompile() { 97 newRegexCache := map[string]*regexMapStruct{} 98 l.Lock() 99 defer l.Unlock() 100 if len(regexCache) == 0 { 101 return 102 } 103 now := time.Now().Unix() 104 for k := range regexCache { 105 if uint(now-regexCache[k].Time) <= regexCacheTimeout { 106 newRegexCache[k] = ®exMapStruct{Value: regexCache[k].Value, Time: now} 107 } 108 } 109 regexCache = newRegexCache 110 } 111 112 func getRegexpCompile(pattern string) (r *regexp.Regexp, err error) { 113 l.RLock() 114 var data *regexMapStruct 115 var ok bool 116 data, ok = regexCache[pattern] 117 l.RUnlock() 118 if ok { 119 r = data.Value 120 return 121 } 122 r, err = regexp.Compile(pattern) 123 if err != nil { 124 return 125 } 126 l.Lock() 127 regexCache[pattern] = ®exMapStruct{Value: r, Time: time.Now().Unix()} 128 l.Unlock() 129 return 130 }