戈朗分流器

时间:2018-09-20 11:31:41

标签: java string go split

下面是 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 个答案:

答案 0 :(得分:3)

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

您可以使用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()函数,则可以使用分隔符创建一个类似集合的映射,然后重用它,因此在传递给{的函数内部{1}},您只需检查strings.FieldFunc()是否在此映射中,就不必调用rune来确定给定的strings.IndexRune()是否为分隔符。

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

它是这样的:

rune

测试:

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
}

输出是相同的。在Go Playground上尝试这个。