Сплиттер на Голанге - PullRequest
       10

Сплиттер на Голанге

0 голосов
/ 20 сентября 2018

Ниже приведен код 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 голосов
/ 20 сентября 2018

Использование регулярного выражения обычно медленнее, чем ручное.Поскольку задача не сложная, решение без регулярных выражений также не сложно.

Вы можете использовать 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 .

...