Teilen Sie eine Zeichenfolge auf Leerzeichen in Go?

115

" word1 word2 word3 word4 "Was wäre angesichts einer Eingabezeichenfolge wie der beste Ansatz, um diese als Array von Zeichenfolgen in Go aufzuteilen? Beachten Sie, dass zwischen jedem Wort eine beliebige Anzahl von Leerzeichen oder Zeichen mit Unicode-Abstand stehen kann.

In Java würde ich nur verwenden someString.trim().split("\\s+").

(Hinweis: Ein möglicher doppelter Split-String mit regulären Ausdrücken in Go liefert keine qualitativ gute Antwort. Bitte geben Sie ein aktuelles Beispiel an, nicht nur einen Link zur Referenz regexpoder oder zu den stringsPaketen.)

ralfoide
quelle

Antworten:

248

Das stringsPaket hat eine FieldsMethode.

someString := "one    two   three four "

words := strings.Fields(someString)

fmt.Println(words, len(words)) // [one two three four] 4

DEMO: http://play.golang.org/p/et97S90cIH

Aus den Dokumenten:

func Fields(s string) []string

Felder teilen die Zeichenfolge sum jede Instanz eines oder mehrerer aufeinanderfolgender Leerzeichen auf und geben ein Array von Teilzeichenfolgen soder eine leere Liste zurück, wenn s nur Leerzeichen enthält.

Ich hasse Faulheit
quelle
1
strings.FieldsIgnoriert leider keine Leerzeichen in zitierten Teilen.
Chmike
@chmike Stimmt, aber sobald Anführungszeichen verwendet werden, müssen Sie eine bestimmte Codierung oder ein bestimmtes Format dekodieren oder analysieren .
mtraceur
@chmike, die Sie möglicherweise shlexfür diesen godoc.org/github.com/google/shlex
akhy
8

Wenn Sie Tipp verwenden: regexp.Split

func (re *Regexp) Split(s string, n int) []string

Teilen Sie Slices s in durch den Ausdruck getrennte Teilzeichenfolgen auf und geben Sie ein Segment der Teilzeichenfolgen zwischen diesen Ausdrucksübereinstimmungen zurück.

Das von dieser Methode zurückgegebene Slice besteht aus allen Teilzeichenfolgen von s, die nicht in dem von FindAllString zurückgegebenen Slice enthalten sind. Wenn ein Ausdruck aufgerufen wird, der keine Metazeichen enthält, entspricht er Zeichenfolgen.SplitN.

Beispiel:

s := regexp.MustCompile("a*").Split("abaabaccadaaae", 5)
// s: ["", "b", "b", "c", "cadaaae"]

Die Anzahl bestimmt die Anzahl der zurückzugebenden Teilzeichenfolgen:

n > 0: at most n substrings; the last substring will be the unsplit remainder.
n == 0: the result is nil (zero substrings)
n < 0: all substrings
zzzz
quelle
3
Dies scheint ein Overkill zu sein
am
@ Tom Aber es ist immer noch interessant, auch wenn es hier nicht die beste Antwort ist. Ich habe diese Antwort positiv bewertet, weil ich etwas gelernt habe.
Denys Séguret
Sie sollten beachten, dass Fields()keine leeren Zeichenfolgen zurückgegeben werden. Die Anzahl der zurückgegebenen Felder variiert also. Wenn Sie versuchen, etwas Konsistentes zu analysieren, funktioniert es für Sie nicht. Möglicherweise müssen Sie Regex verwenden, wenn a FieldsFunc()auch nicht funktioniert.
Tom
3

Ich habe mir Folgendes ausgedacht, aber das scheint etwas zu ausführlich:

import "regexp"
r := regexp.MustCompile("[^\\s]+")
r.FindAllString("  word1   word2 word3   word4  ", -1)

welches bewertet wird zu:

[]string{"word1", "word2", "word3", "word4"}

Gibt es einen kompakteren oder idiomatischeren Ausdruck?

ralfoide
quelle