Golang 中的分割器

Jun*_*d s 3 java string split go

下面是Java代码,我需要Go中类似的代码:

List<String> tokens = Lists.newArrayList(Splitter.on(CharMatcher.anyOf("[]//"))
.trimResults().omitEmptyStrings().split(entry.getValue()))
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的:

re := regexp.MustCompile(`[//]`)
tokens := re.Split(entry, -1)
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 5

使用正则表达式通常比手动执行慢。由于任务并不复杂,因此非正则表达式解决方案也不复杂。

您可以使用strings.FieldsFunc()一组字符来分割字符串,并strings.TrimSpace()去除前导和尾随空格。

这是一个简单的函数,可以完成您想要的操作:

func split(s, sep string) (tokens []string) {
    fields := strings.FieldsFunc(s, func(r rune) bool {
        return strings.IndexRune(sep, r) != -1
    })
    for _, s2 := range fields {
        s2 = strings.TrimSpace(s2)
        if s2 != "" {
            tokens = append(tokens, s2)
        }
    }
    return
}
Run Code Online (Sandbox Code Playgroud)

测试它:

fmt.Printf("%q\n", split("a,b;c, de; ; fg ", ",;"))
fmt.Printf("%q\n", split("a[b]c[ de/ / fg ", "[]/"))
Run Code Online (Sandbox Code Playgroud)

输出(在Go Playground上尝试):

["a" "b" "c" "de" "fg"]
["a" "b" "c" "de" "fg"]
Run Code Online (Sandbox Code Playgroud)

改进

如果性能是一个问题,并且您必须split()多次调用此函数,那么从分隔符字符创建一个类似集合的映射并重用它会是有利可图的,因此在传递给 的函数内strings.FieldFunc(),您可以简单地检查是否rune在这个映射,所以你不需要调用来strings.IndexRune()决定给定的是否rune是分隔符。

如果分隔符字符很少(例如 1-3 个字符),那么性能提升可能并不显着,但如果分隔符字符较多,则使用映射可以显着提高性能。

它可能是这样的:

var (
    sep1 = map[rune]bool{',': true, ';': true}
    sep2 = map[rune]bool{'[': true, ']': true, '/': true}
)

func split(s string, sep map[rune]bool) (tokens []string) {
    fields := strings.FieldsFunc(s, func(r rune) bool {
        return sep[r]
    })
    for _, s2 := range fields {
        s2 = strings.TrimSpace(s2)
        if s2 != "" {
            tokens = append(tokens, s2)
        }
    }
    return
}
Run Code Online (Sandbox Code Playgroud)

测试它:

fmt.Printf("%q\n", split("a,b;c, de; ; fg ", sep1))
fmt.Printf("%q\n", split("a[b]c[ de/ / fg ", sep2))
Run Code Online (Sandbox Code Playgroud)

输出是一样的。在Go Playground上试试这个。