为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 中的拆分器

Golang 中的拆分器

Cats萌萌 2021-09-29 17:05:22
下面是Java代码,我在Go 中需要类似的东西:List<String> tokens = Lists.newArrayList(Splitter.on(CharMatcher.anyOf("[]//")).trimResults().omitEmptyStrings().split(entry.getValue()))这是我尝试过的:re := regexp.MustCompile(`[//]`)tokens := re.Split(entry, -1)
查看完整描述

1 回答

?
元芳怎么了

TA贡献1798条经验 获得超7个赞

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


您可以使用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

}

测试它:


fmt.Printf("%q\n", split("a,b;c, de; ; fg ", ",;"))

fmt.Printf("%q\n", split("a[b]c[ de/ / fg ", "[]/"))

输出(在Go Playground上试试):


["a" "b" "c" "de" "fg"]

["a" "b" "c" "de" "fg"]

改进

如果性能是一个问题并且您必须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

}

测试它:


fmt.Printf("%q\n", split("a,b;c, de; ; fg ", sep1))

fmt.Printf("%q\n", split("a[b]c[ de/ / fg ", sep2))

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


查看完整回答
反对 回复 2021-09-29
  • 1 回答
  • 0 关注
  • 148 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信