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

     1  package strings
     2  
     3  import (
     4  	"context"
     5  	"strings"
     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  // FIND_FIRST returns the position of the first occurrence of the string search inside the string text. Positions start at 0.
    13  // @param {String} str - The source string.
    14  // @param {String} search - The string to seek.
    15  // @param {Int} [start] - Limit the search to a subset of the text, beginning at start.
    16  // @param {Int} [end] - Limit the search to a subset of the text, ending at end
    17  // @return {Int} - The character position of the match. If search is not contained in text, -1 is returned. If search is empty, start is returned.
    18  func FindFirst(_ context.Context, args ...core.Value) (core.Value, error) {
    19  	err := core.ValidateArgs(args, 2, 4)
    20  
    21  	if err != nil {
    22  		return values.NewInt(-1), err
    23  	}
    24  
    25  	argsCount := len(args)
    26  
    27  	text := args[0].String()
    28  	runes := []rune(text)
    29  	search := args[1].String()
    30  	start := values.NewInt(0)
    31  	end := values.NewInt(len(text))
    32  
    33  	if argsCount == 3 {
    34  		arg3 := args[2]
    35  
    36  		if arg3.Type() == types.Int {
    37  			start = arg3.(values.Int)
    38  		}
    39  	}
    40  
    41  	if argsCount == 4 {
    42  		arg4 := args[3]
    43  
    44  		if arg4.Type() == types.Int {
    45  			end = arg4.(values.Int)
    46  		}
    47  	}
    48  
    49  	found := strings.Index(string(runes[start:end]), search)
    50  
    51  	if found > -1 {
    52  		return values.NewInt(found + int(start)), nil
    53  	}
    54  
    55  	return values.NewInt(found), nil
    56  }
    57  
    58  // FIND_LAST returns the position of the last occurrence of the string search inside the string text. Positions start at 0.
    59  // @param {String} src - The source string.
    60  // @param {String} search - The string to seek.
    61  // @param {Int} [start] - Limit the search to a subset of the text, beginning at start.
    62  // @param {Int} [end] - Limit the search to a subset of the text, ending at end
    63  // @return {Int} - The character position of the match. If search is not contained in text, -1 is returned. If search is empty, start is returned.
    64  func FindLast(_ context.Context, args ...core.Value) (core.Value, error) {
    65  	err := core.ValidateArgs(args, 2, 4)
    66  
    67  	if err != nil {
    68  		return values.NewInt(-1), err
    69  	}
    70  
    71  	argsCount := len(args)
    72  
    73  	text := args[0].String()
    74  	runes := []rune(text)
    75  	search := args[1].String()
    76  	start := values.NewInt(0)
    77  	end := values.NewInt(len(text))
    78  
    79  	if argsCount == 3 {
    80  		arg3 := args[2]
    81  
    82  		if arg3.Type() == types.Int {
    83  			start = arg3.(values.Int)
    84  		}
    85  	}
    86  
    87  	if argsCount == 4 {
    88  		arg4 := args[3]
    89  
    90  		if arg4.Type() == types.Int {
    91  			end = arg4.(values.Int)
    92  		}
    93  	}
    94  
    95  	found := strings.LastIndex(string(runes[start:end]), search)
    96  
    97  	if found > -1 {
    98  		return values.NewInt(found + int(start)), nil
    99  	}
   100  
   101  	return values.NewInt(found), nil
   102  }