Skip to content

Commit e7231e7

Browse files
committed
add regular expression comparator
1 parent 4d0207e commit e7231e7

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

comparators.go

+25
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package grules
22

3+
import "regexp"
4+
35
// Comparator is a function that should evaluate two values and return
46
// the true if the comparison is true, or false if the comparison is
57
// false
@@ -126,6 +128,29 @@ func greaterThanEqual(a, b interface{}) bool {
126128
}
127129
}
128130

131+
func regex(a, b interface{}) bool {
132+
switch a.(type) {
133+
case string:
134+
at, ok := a.(string)
135+
if !ok {
136+
return false
137+
}
138+
bt, ok := b.(string)
139+
if !ok {
140+
return false
141+
}
142+
143+
r, err := regexp.Compile(bt)
144+
if err != nil {
145+
return false
146+
}
147+
148+
return r.MatchString(at)
149+
default:
150+
return false
151+
}
152+
}
153+
129154
// contains will return true if a contains b. We assume
130155
// that the first interface is a slice. If you need b to be a slice
131156
// consider using oneOf

comparators_test.go

+29
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,35 @@ func BenchmarkGreaterThanEqual(b *testing.B) {
160160
}
161161
}
162162

163+
func TestRegex(t *testing.T) {
164+
cases := []testCase{
165+
testCase{args: []interface{}{"a", "a"}, expected: true},
166+
testCase{args: []interface{}{"a", "[ab]"}, expected: true},
167+
testCase{args: []interface{}{"c", "[ab]"}, expected: false},
168+
testCase{args: []interface{}{"abc", "c$"}, expected: true},
169+
testCase{args: []interface{}{float64(1), float64(1)}, expected: false},
170+
}
171+
172+
for i, c := range cases {
173+
res := regex(c.args[0], c.args[1])
174+
if res != c.expected {
175+
t.Fatalf("expected case %d to be %v, got %v", i, c.expected, res)
176+
}
177+
}
178+
}
179+
180+
func BenchmarkRegex(b *testing.B) {
181+
for i := 0; i < b.N; i++ {
182+
regex("a", "a")
183+
}
184+
}
185+
186+
func BenchmarkRegexPhone(b *testing.B) {
187+
for i := 0; i < b.N; i++ {
188+
regex("+1(555) 555-5555", "\\+\\d\\(\\d+\\) \\d+-\\d+")
189+
}
190+
}
191+
163192
func TestContains(t *testing.T) {
164193
cases := []testCase{
165194
testCase{args: []interface{}{[]interface{}{"a", "b"}, "a"}, expected: true},

rule.go

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ var defaultComparators = map[string]Comparator{
2424
"ncontains": notContains,
2525
"oneof": oneOf,
2626
"noneof": noneOf,
27+
"regex": regex,
2728
}
2829

2930
// Rule is a our smallest unit of measure, each rule will be

0 commit comments

Comments
 (0)