diff --git a/docs/types/string.md b/docs/types/string.md index 606e90a9..3819802c 100644 --- a/docs/types/string.md +++ b/docs/types/string.md @@ -346,6 +346,12 @@ If `n` is negative it will replace all occurrencies: "string".replace("i", "o", -1) # "strong" ``` +You can also replace an array of characters: + +``` bash +"string".replace(["i", "g"], "o", -1) # "strono" +``` + ### title() Titlecases the string: diff --git a/evaluator/evaluator_test.go b/evaluator/evaluator_test.go index 01903c8f..a1d28328 100644 --- a/evaluator/evaluator_test.go +++ b/evaluator/evaluator_test.go @@ -895,6 +895,7 @@ c")`, []string{"a", "b", "c"}}, {`[1,2,3].slice(-1, 3)`, []int{3}}, {`[1,2,3].slice(-1, 1)`, []int{3}}, {`"a".replace("a", "b", -1)`, "b"}, + {`"ac".replace(["a", "c"], "b", -1)`, "bb"}, {`"a".str()`, "a"}, {`1.str()`, "1"}, {`[1].str()`, "[1]"}, diff --git a/evaluator/functions.go b/evaluator/functions.go index b72f035c..c336ba1b 100644 --- a/evaluator/functions.go +++ b/evaluator/functions.go @@ -1165,14 +1165,27 @@ func repeatFn(tok token.Token, args ...object.Object) object.Object { return &object.String{Token: tok, Value: strings.Repeat(args[0].(*object.String).Value, int(args[1].(*object.Number).Value))} } -// replace("abc", "b", "f", -1) +// replace("abd", "d", "c", -1) +// replace("abc", ["a", "b"], "c", -1) func replaceFn(tok token.Token, args ...object.Object) object.Object { - err := validateArgs(tok, "replace", args, 4, [][]string{{object.STRING_OBJ}, {object.STRING_OBJ}, {object.STRING_OBJ}, {object.NUMBER_OBJ}}) + err := validateArgs(tok, "replace", args, 4, [][]string{{object.STRING_OBJ}, {object.STRING_OBJ, object.ARRAY_OBJ}, {object.STRING_OBJ}, {object.NUMBER_OBJ}}) if err != nil { return err } - return &object.String{Token: tok, Value: strings.Replace(args[0].(*object.String).Value, args[1].(*object.String).Value, args[2].(*object.String).Value, int(args[3].(*object.Number).Value))} + original := args[0].(*object.String).Value + replacement := args[2].(*object.String).Value + n := int(args[3].(*object.Number).Value) + + if characters, ok := args[1].(*object.Array); ok { + for _, c := range characters.Elements { + original = strings.Replace(original, c.Inspect(), replacement, n) + } + + return &object.String{Token: tok, Value: original} + } + + return &object.String{Token: tok, Value: strings.Replace(original, args[1].(*object.String).Value, replacement, n)} } // title("some thing")