github.com/MontFerret/ferret@v0.18.0/pkg/runtime/expressions/operators/regexp.go (about) 1 package operators 2 3 import ( 4 "context" 5 "regexp" 6 7 "github.com/MontFerret/ferret/pkg/runtime/core" 8 "github.com/MontFerret/ferret/pkg/runtime/values" 9 ) 10 11 type ( 12 RegexpOperatorVariant int 13 14 RegexpOperator struct { 15 *baseOperator 16 variant RegexpOperatorVariant 17 } 18 ) 19 20 const ( 21 RegexpOperatorVariantNegative RegexpOperatorVariant = 0 22 RegexpOperatorVariantPositive RegexpOperatorVariant = 1 23 ) 24 25 var regexpVariants = map[string]RegexpOperatorVariant{ 26 "!~": RegexpOperatorVariantNegative, 27 "=~": RegexpOperatorVariantPositive, 28 } 29 30 func NewRegexpOperator( 31 src core.SourceMap, 32 left core.Expression, 33 right core.Expression, 34 operatorStr string, 35 ) (*RegexpOperator, error) { 36 variant, exists := regexpVariants[operatorStr] 37 38 if !exists { 39 return nil, core.Error(core.ErrInvalidArgument, "operator") 40 } 41 42 return &RegexpOperator{ 43 &baseOperator{ 44 src, 45 left, 46 right, 47 }, 48 variant, 49 }, nil 50 } 51 52 func (operator *RegexpOperator) Type() RegexpOperatorVariant { 53 return operator.variant 54 } 55 56 func (operator *RegexpOperator) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) { 57 left, err := operator.left.Exec(ctx, scope) 58 59 if err != nil { 60 return nil, err 61 } 62 63 right, err := operator.right.Exec(ctx, scope) 64 65 if err != nil { 66 return nil, err 67 } 68 69 return operator.Eval(ctx, left, right) 70 } 71 72 func (operator *RegexpOperator) Eval(_ context.Context, left, right core.Value) (core.Value, error) { 73 leftStr := left.String() 74 rightStr := right.String() 75 76 r, err := regexp.Compile(rightStr) 77 78 if err != nil { 79 return values.None, err 80 } 81 82 if operator.variant == RegexpOperatorVariantPositive { 83 return values.NewBoolean(r.MatchString(leftStr)), nil 84 } 85 86 return values.NewBoolean(!r.MatchString(leftStr)), nil 87 }