-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathregexes.go
More file actions
75 lines (62 loc) · 3.23 KB
/
regexes.go
File metadata and controls
75 lines (62 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package firevault
import (
"regexp"
"sync"
)
// regexCache provides thread-safe lazy compilation and caching of regex patterns
type regexCache struct {
mu sync.RWMutex
patterns map[string]*regexp.Regexp
}
// global regex cache instance
var rxCache = ®exCache{
patterns: make(map[string]*regexp.Regexp),
}
// getOrCompile retrieves a cached regex or compiles it if not present
func (rc *regexCache) getOrCompile(pattern string) *regexp.Regexp {
// fast path: check if already compiled (read lock)
rc.mu.RLock()
if rx, exists := rc.patterns[pattern]; exists {
rc.mu.RUnlock()
return rx
}
rc.mu.RUnlock()
// slow path: compile and cache (write lock)
rc.mu.Lock()
defer rc.mu.Unlock()
// double-check after acquiring write lock (another goroutine may have compiled it)
if rx, exists := rc.patterns[pattern]; exists {
return rx
}
rx := regexp.MustCompile(pattern)
rc.patterns[pattern] = rx
return rx
}
// regex pattern constants
const (
emailPattern = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22))))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
lowerUpperBoundaryPattern = `([a-z])([A-Z])`
upperDigitBoundaryPattern = `([A-Z])([0-9])`
lowerDigitBoundaryPattern = `([a-z])([0-9])`
digitInstancePattern = `\d`
)
// emailRegex returns the compiled email validation regex
func emailRegex() *regexp.Regexp {
return rxCache.getOrCompile(emailPattern)
}
// lowerUpperBoundaryRegex returns the compiled lower-upper boundary regex
func lowerUpperBoundaryRegex() *regexp.Regexp {
return rxCache.getOrCompile(lowerUpperBoundaryPattern)
}
// upperDigitBoundaryRegex returns the compiled upper-digit boundary regex
func upperDigitBoundaryRegex() *regexp.Regexp {
return rxCache.getOrCompile(upperDigitBoundaryPattern)
}
// lowerDigitBoundaryRegex returns the compiled lower-digit boundary regex
func lowerDigitBoundaryRegex() *regexp.Regexp {
return rxCache.getOrCompile(lowerDigitBoundaryPattern)
}
// digitInstanceRegex returns the compiled digit instance regex
func digitInstanceRegex() *regexp.Regexp {
return rxCache.getOrCompile(digitInstancePattern)
}