I need to combine strings.SplitN and strings.SplitFunc. the input string might have any kind of whitespace and I just need the first two splitted substrings and remaining string should be parsed in another run. The SplitN function splits the input up to the N parameter but just consider space not whitespace. You can define your special splitter in SplitFunc, in my case something like this:
f := func(r rune) bool {
return unicode.IsSpace(r)
}
but I can not define the number of substring in SplitFunc.
the function strings.Fields is also not useful since there is no limit in this function.
regexp Split appears to do what you require
s := regexp.MustCompile("[[:space:]]+")
r:=s.Split("the final conflict. Of Cheese", 3)
fmt.Println("first two ",r[:2])
fmt.Println("remaining ",r[2:])
}
You can use strings.IndexFunc in a loop while trimming the string from left based on the found index.
A naive implementation could look like:
func findN(s string, limit int) []string {
var found []string
for i := 0; i < limit; i++ {
nextIndex := strings.IndexFunc(s, unicode.IsSpace)
if nextIndex < 0 {
break
}
found = append(found, s[:nextIndex])
s = s[nextIndex+1:]
}
return found
}
The whole code is here: https://play.golang.org/p/IZb8aV20ILW
I wrote the answer in this way: first use string.Fields then grab as much as substring I want and remove them also from the source string
package main
import (
"fmt"
"strings"
)
func main() {
str := " "
substr, len := findN(str, 2)
fmt.Printf("%q
%d", substr, len)
}
func findN(str string, limit int) ([]string, int) {
if len(str) <= 0 {
return nil, 0
}
var substr []string
for i := 0; i < limit; i++ {
splitedS := strings.Fields(str)
if len(splitedS) < 1 {
break
}
v := splitedS[0]
substr = append(substr, v)
str = strings.TrimSpace(str)
str = strings.TrimPrefix(str, v)
str = strings.TrimSpace(str)
}
str = strings.TrimSpace(str)
if str != "" {
substr = append(substr, str)
}
return substr, len(substr)
}