-
-
Notifications
You must be signed in to change notification settings - Fork 163
/
glob.go
92 lines (87 loc) · 1.78 KB
/
glob.go
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package playwright
import (
"regexp"
"strings"
)
var escapedChars = map[rune]bool{
'$': true,
'^': true,
'+': true,
'.': true,
'*': true,
'(': true,
')': true,
'|': true,
'\\': true,
'?': true,
'{': true,
'}': true,
'[': true,
']': true,
}
func globMustToRegex(glob string) *regexp.Regexp {
tokens := []string{"^"}
inGroup := false
for i := 0; i < len(glob); i++ {
c := rune(glob[i])
if c == '\\' && i+1 < len(glob) {
char := rune(glob[i+1])
if _, ok := escapedChars[char]; ok {
tokens = append(tokens, "\\"+string(char))
} else {
tokens = append(tokens, string(char))
}
i++
} else if c == '*' {
beforeDeep := rune(0)
if i > 0 {
beforeDeep = rune(glob[i-1])
}
starCount := 1
for i+1 < len(glob) && glob[i+1] == '*' {
starCount++
i++
}
afterDeep := rune(0)
if i+1 < len(glob) {
afterDeep = rune(glob[i+1])
}
isDeep := starCount > 1 && (beforeDeep == '/' || beforeDeep == 0) && (afterDeep == '/' || afterDeep == 0)
if isDeep {
tokens = append(tokens, "((?:[^/]*(?:/|$))*)")
i++
} else {
tokens = append(tokens, "([^/]*)")
}
} else {
switch c {
case '?':
tokens = append(tokens, ".")
case '[':
tokens = append(tokens, "[")
case ']':
tokens = append(tokens, "]")
case '{':
inGroup = true
tokens = append(tokens, "(")
case '}':
inGroup = false
tokens = append(tokens, ")")
case ',':
if inGroup {
tokens = append(tokens, "|")
} else {
tokens = append(tokens, string(c))
}
default:
if _, ok := escapedChars[c]; ok {
tokens = append(tokens, "\\"+string(c))
} else {
tokens = append(tokens, string(c))
}
}
}
}
tokens = append(tokens, "$")
return regexp.MustCompile(strings.Join(tokens, ""))
}