下面是 Java 代码,在 Go 中我需要类似的内容:
List<String> tokens = Lists.newArrayList(Splitter.on(CharMatcher.anyOf("[]//"))
.trimResults().omitEmptyStrings().split(entry.getValue()))
这是我尝试过的:
re := regexp.MustCompile(`[//]`)
tokens := re.Split(entry, -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上尝试这个。