Использование регулярного выражения обычно медленнее, чем ручное.Поскольку задача не сложная, решение без регулярных выражений также не сложно.
Вы можете использовать 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 символа), но если выиметь гораздо больше, используя карту может значительно улучшить производительностьnce.
Вот как это может выглядеть:
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 .