-
Notifications
You must be signed in to change notification settings - Fork 0
/
extractor.go
88 lines (79 loc) · 1.63 KB
/
extractor.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
package varparse
import (
"errors"
"fmt"
"regexp"
)
type extractor struct {
varStart string
varEnd string
executor *regexp.Regexp
}
type Extractor interface {
Extract(v string) map[string]string
Compile() (err error)
}
var (
MissStartFlagError = errors.New(`miss start flag`)
MissEndFlagError = errors.New(`miss end flag`)
)
func NewExtractor(start, end string) Extractor {
return &extractor{varStart: start, varEnd: end}
}
func ExtractorOf() Extractor {
return NewExtractor("${", "}")
}
func (e *extractor) Compile() (err error) {
if e.varStart == "" {
return MissStartFlagError
}
if e.varEnd == "" {
return MissEndFlagError
}
var (
end = RegexpPrevProcess([]rune(e.varEnd))
start = RegexpPrevProcess([]rune(e.varStart))
expr = fmt.Sprintf(`(%s([\w_-]+)%s)`, string(start), string(end))
)
e.executor, err = regexp.Compile(expr)
return err
}
func (e *extractor) Extract(v string) map[string]string {
if e.executor == nil {
if err := e.Compile(); err != nil {
return map[string]string{}
}
}
var (
extractValue = make(map[string]string)
values = e.executor.FindAllStringSubmatch(v, -1)
)
for _, v := range values {
extractValue[v[len(v)-1]] = v[0]
}
return extractValue
}
func RegexpPrevProcess(word []rune) []rune {
if len(word) <= 0 {
return word
}
var (
result []rune
metaWords = map[rune]struct{}{
'?': {}, '$': {},
'{': {}, '}': {},
'\\': {}, '.': {},
'*': {}, '+': {},
'[': {}, ']': {},
'|': {},
}
)
for _, v := range word {
if _, ok := metaWords[v]; !ok {
result = append(result, v)
} else {
result = append(result, '\\', v)
}
}
return result
}