github.com/MontFerret/ferret@v0.18.0/pkg/stdlib/strings/like.go (about)

     1  package strings
     2  
     3  import (
     4  	"context"
     5  	"regexp"
     6  	"strings"
     7  
     8  	"github.com/gobwas/glob"
     9  
    10  	"github.com/MontFerret/ferret/pkg/runtime/core"
    11  	"github.com/MontFerret/ferret/pkg/runtime/values"
    12  )
    13  
    14  var (
    15  	deprecatedLikeSyntax = regexp.MustCompile("[%_]")
    16  )
    17  
    18  // LIKE checks whether the pattern search is contained in the string text, using wildcard matching.
    19  // @param {String} str - The string to search in.
    20  // @param {String} search - A search pattern that can contain the wildcard characters.
    21  // @param {Boolean} caseInsensitive - If set to true, the matching will be case-insensitive. The default is false.
    22  // @return {Boolean} - Returns true if the pattern is contained in text, and false otherwise.
    23  func Like(_ context.Context, args ...core.Value) (core.Value, error) {
    24  	err := core.ValidateArgs(args, 2, 3)
    25  
    26  	if err != nil {
    27  		return values.False, err
    28  	}
    29  
    30  	str := args[0].String()
    31  	pattern := args[1].String()
    32  
    33  	if len(pattern) == 0 {
    34  		return values.NewBoolean(len(str) == 0), nil
    35  	}
    36  
    37  	// TODO: Remove me in next releases
    38  	replaced := deprecatedLikeSyntax.ReplaceAllFunc([]byte(pattern), func(b []byte) []byte {
    39  		str := string(b)
    40  
    41  		switch str {
    42  		case "%":
    43  			return []byte("*")
    44  		case "_":
    45  			return []byte("?")
    46  		default:
    47  			return b
    48  		}
    49  	})
    50  
    51  	pattern = string(replaced)
    52  
    53  	if len(args) > 2 {
    54  		if values.ToBoolean(args[2]) {
    55  			str = strings.ToLower(str)
    56  			pattern = strings.ToLower(pattern)
    57  		}
    58  	}
    59  
    60  	g, err := glob.Compile(pattern)
    61  
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	return values.NewBoolean(g.Match(str)), nil
    67  }