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

     1  package strings
     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  	"github.com/MontFerret/ferret/pkg/runtime/values/types"
    10  )
    11  
    12  // REGEX_MATCH returns the matches in the given string text, using the regex.
    13  // @param {String} str - The string to search in.
    14  // @param {String} expression - A regular expression to use for matching the text.
    15  // @param {Boolean} caseInsensitive - If set to true, the matching will be case-insensitive. The default is false.
    16  // @return {Any[]} - An array of strings containing the matches.
    17  func RegexMatch(_ context.Context, args ...core.Value) (core.Value, error) {
    18  	err := core.ValidateArgs(args, 2, 3)
    19  
    20  	if err != nil {
    21  		return values.None, err
    22  	}
    23  
    24  	text := args[0].String()
    25  	exp := args[1].String()
    26  
    27  	if len(args) > 2 {
    28  		if args[2] == values.True {
    29  			exp = "(?i)" + exp
    30  		}
    31  	}
    32  
    33  	reg, err := regexp.Compile(exp)
    34  
    35  	if err != nil {
    36  		return values.None, err
    37  	}
    38  
    39  	matches := reg.FindAllStringSubmatch(text, -1)
    40  	res := values.NewArray(10)
    41  
    42  	if len(matches) == 0 {
    43  		return res, nil
    44  	}
    45  
    46  	for _, m := range matches[0] {
    47  		res.Push(values.NewString(m))
    48  	}
    49  
    50  	return res, nil
    51  }
    52  
    53  // REGEX_SPLIT splits the given string text into a list of strings, using the separator.
    54  // @param {String} str - The string to split.
    55  // @param {String} expression - A regular expression to use for splitting the text.
    56  // @param {Boolean} caseInsensitive - If set to true, the matching will be case-insensitive. The default is false.
    57  // @param {Int} limit - Limit the number of split values in the result. If no limit is given, the number of splits returned is not bounded.
    58  // @return {Any[]} - An array of strings splitted by the expression.
    59  func RegexSplit(_ context.Context, args ...core.Value) (core.Value, error) {
    60  	err := core.ValidateArgs(args, 2, 4)
    61  
    62  	if err != nil {
    63  		return values.None, err
    64  	}
    65  
    66  	text := args[0].String()
    67  	exp := args[1].String()
    68  	limit := -1
    69  
    70  	if len(args) > 2 {
    71  		if args[2].Type() == types.Int {
    72  			limit = int(args[2].(values.Int))
    73  		}
    74  	}
    75  
    76  	reg, err := regexp.Compile(exp)
    77  
    78  	if err != nil {
    79  		return values.None, err
    80  	}
    81  
    82  	matches := reg.Split(text, limit)
    83  	res := values.NewArray(10)
    84  
    85  	if len(matches) == 0 {
    86  		return res, nil
    87  	}
    88  
    89  	for _, m := range matches {
    90  		res.Push(values.NewString(m))
    91  	}
    92  
    93  	return res, nil
    94  }
    95  
    96  // REGEX_TEST test whether the regexp has at least one match in the given text.
    97  // @param {String} str - The string to test.
    98  // @param {String} expression - A regular expression to use for splitting the text.
    99  // @param {Boolean} [caseInsensitive=False] - If set to true, the matching will be case-insensitive.
   100  // @return {Boolean} - Returns true if the pattern is contained in text, and false otherwise.
   101  func RegexTest(_ context.Context, args ...core.Value) (core.Value, error) {
   102  	err := core.ValidateArgs(args, 2, 3)
   103  
   104  	if err != nil {
   105  		return values.None, err
   106  	}
   107  
   108  	text := args[0].String()
   109  	exp := args[1].String()
   110  
   111  	if len(args) > 2 {
   112  		if args[2] == values.True {
   113  			exp = "(?i)" + exp
   114  		}
   115  	}
   116  
   117  	reg, err := regexp.Compile(exp)
   118  
   119  	if err != nil {
   120  		return values.None, err
   121  	}
   122  
   123  	matches := reg.MatchString(text)
   124  
   125  	return values.NewBoolean(matches), nil
   126  }
   127  
   128  // REGEX_REPLACE replace every substring matched with the regexp with a given string.
   129  // @param {String} str - The string to split.
   130  // @param {String} expression - A regular expression search pattern.
   131  // @param {String} replacement - The string to replace the search pattern with
   132  // @param {Boolean} [caseInsensitive=False] - If set to true, the matching will be case-insensitive.
   133  // @return {String} - Returns the string text with the search regex pattern replaced with the replacement string wherever the pattern exists in text
   134  func RegexReplace(_ context.Context, args ...core.Value) (core.Value, error) {
   135  	err := core.ValidateArgs(args, 3, 4)
   136  
   137  	if err != nil {
   138  		return values.EmptyString, err
   139  	}
   140  
   141  	text := args[0].String()
   142  	exp := args[1].String()
   143  	repl := args[2].String()
   144  
   145  	if len(args) > 3 {
   146  		if args[3] == values.True {
   147  			exp = "(?i)" + exp
   148  		}
   149  	}
   150  
   151  	reg, err := regexp.Compile(exp)
   152  
   153  	if err != nil {
   154  		return values.None, err
   155  	}
   156  
   157  	out := reg.ReplaceAllString(text, repl)
   158  
   159  	return values.NewString(out), nil
   160  }