drrc61668568 2018-09-20 11:31
浏览 74
已采纳

戈朗分流器

Below is the Java code, I need something similar in Go:

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

This is what I have tried:

re := regexp.MustCompile(`[//]`)
tokens := re.Split(entry, -1)
  • 写回答

1条回答 默认 最新

  • duanliao3826 2018-09-20 11:53
    关注

    Using regexp is usually slower than doing it manually. Since the task is not complex, the non-regexp solution isn't complicated either.

    You may use strings.FieldsFunc() to split a string on a set of characters, and strings.TrimSpace() to strip off leading and trailing white-spaces.

    Here's a simple function doing what you want:

    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
    }
    

    Testing it:

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

    Output (try it on the Go Playground):

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

    Improvements

    If performance is an issue and you have to call this split() function many times, it would be profitable to create a set-like map from the separator characters, and reuse that, so inside the function passed to strings.FieldFunc(), you can simply check if the rune is in this map, so you would not need to call strings.IndexRune() to decide if the given rune is a separator character.

    The performance gain might not be significant if you have few separator characters (like 1-3 characters), but if you would have a lot more, using a map could significantly improve performance.

    This is how it could look like:

    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
    }
    

    Testing it:

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

    Output is the same. Try this one on the Go Playground.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?
  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)
  • ¥65 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi