forked from MontFerret/ferret
/
regex.go
160 lines (122 loc) · 4.12 KB
/
regex.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package strings
import (
"context"
"regexp"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/MontFerret/ferret/pkg/runtime/values/types"
)
// RegexMatch returns the matches in the given string text, using the regex.
// @param text (String) - The string to search in.
// @param regex (String) - A regular expression to use for matching the text.
// @param caseInsensitive (Boolean) - If set to true, the matching will be case-insensitive. The default is false.
// @return (Array) - An array of strings containing the matches.
func RegexMatch(_ context.Context, args ...core.Value) (core.Value, error) {
err := core.ValidateArgs(args, 2, 3)
if err != nil {
return values.None, err
}
text := args[0].String()
exp := args[1].String()
if len(args) > 2 {
if args[2] == values.True {
exp = "(?i)" + exp
}
}
reg, err := regexp.Compile(exp)
if err != nil {
return values.None, err
}
matches := reg.FindAllStringSubmatch(text, -1)
res := values.NewArray(10)
if len(matches) == 0 {
return res, nil
}
for _, m := range matches[0] {
res.Push(values.NewString(m))
}
return res, nil
}
// RegexSplit splits the given string text into a list of strings, using the separator.
// @param text (String) - The string to split.
// @param regex (String) - A regular expression to use for splitting the text.
// @param caseInsensitive (Boolean) - If set to true, the matching will be case-insensitive. The default is false.
// @param limit (Int) - Limit the number of split values in the result. If no limit is given, the number of splits returned is not bounded.
// @return (Array) - An array of strings splited by teh expression.
func RegexSplit(_ context.Context, args ...core.Value) (core.Value, error) {
err := core.ValidateArgs(args, 2, 4)
if err != nil {
return values.None, err
}
text := args[0].String()
exp := args[1].String()
limit := -1
if len(args) > 2 {
if args[2].Type() == types.Int {
limit = int(args[2].(values.Int))
}
}
reg, err := regexp.Compile(exp)
if err != nil {
return values.None, err
}
matches := reg.Split(text, limit)
res := values.NewArray(10)
if len(matches) == 0 {
return res, nil
}
for _, m := range matches {
res.Push(values.NewString(m))
}
return res, nil
}
// RegexTest test wether the regexp has at least one match in the given text.
// @param text (String) - The string to split.
// @param regex (String) - A regular expression to use for splitting the text.
// @param caseInsensitive (Boolean) - If set to true, the matching will be case-insensitive. The default is false.
// @return (Boolean) - Returns true if the pattern is contained in text, and false otherwise.
func RegexTest(_ context.Context, args ...core.Value) (core.Value, error) {
err := core.ValidateArgs(args, 2, 3)
if err != nil {
return values.None, err
}
text := args[0].String()
exp := args[1].String()
if len(args) > 2 {
if args[2] == values.True {
exp = "(?i)" + exp
}
}
reg, err := regexp.Compile(exp)
if err != nil {
return values.None, err
}
matches := reg.MatchString(text)
return values.NewBoolean(matches), nil
}
// RegexReplace replace every substring matched with the regexp with a given string.
// @param text (String) - The string to split.
// @param regex (String) - A regular expression search pattern.
// @param replacement (String) - The string to replace the search pattern with
// @param caseInsensitive (Boolean) - If set to true, the matching will be case-insensitive. The default is false.
// @return (String) - Returns the string text with the search regex pattern replaced with the replacement string wherever the pattern exists in text
func RegexReplace(_ context.Context, args ...core.Value) (core.Value, error) {
err := core.ValidateArgs(args, 3, 4)
if err != nil {
return values.EmptyString, err
}
text := args[0].String()
exp := args[1].String()
repl := args[2].String()
if len(args) > 3 {
if args[3] == values.True {
exp = "(?i)" + exp
}
}
reg, err := regexp.Compile(exp)
if err != nil {
return values.None, err
}
out := reg.ReplaceAllString(text, repl)
return values.NewString(out), nil
}