Podzielić ciąg na białe znaki w Go?

115

Biorąc pod uwagę ciąg wejściowy, taki jak " word1 word2 word3 word4 ", jakie byłoby najlepsze podejście do podzielenia go jako tablicy ciągów w Go? Zauważ, że między każdym słowem może występować dowolna liczba spacji lub znaków odstępu Unicode.

W Javie po prostu użyłbym someString.trim().split("\\s+").

(Uwaga: możliwy duplikat ciągu Split przy użyciu wyrażenia regularnego w Go nie daje żadnej dobrej odpowiedzi. Podaj rzeczywisty przykład, a nie tylko link do odwołania do regexplub stringspakietów).

ralfoide
źródło

Odpowiedzi:

248

stringsPakiet ma Fieldsmetody.

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

Z dokumentów:

func Fields(s string) []string

Pola dzielą ciąg swokół każdego wystąpienia jednego lub więcej kolejnych znaków odstępu, zwracając tablicę podciągów slub pustą listę, jeśli s zawiera tylko odstępy.

Nienawidzę lenistwa
źródło
1
Niestety strings.Fieldsnie ignoruje spacji w cytowanych częściach.
chmike
@chmike Prawda, ale w momencie, gdy w grę wchodzą cytaty, jesteś w branży dekodowania lub analizowania określonego kodowania lub formatu .
mtraceur
@chmike może trzeba shlexdo tego godoc.org/github.com/google/shlex
akhy
8

Jeśli używasz tip: regexp.Split

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

Podziel plasterki na podciągi oddzielone wyrażeniem i zwróć wycinek podciągów między tymi dopasowanymi wyrażeniami.

Wycinek zwracany przez tę metodę składa się ze wszystkich podciągów s, które nie są zawarte w wycinku zwróconym przez FindAllString. W przypadku wywołania wyrażenia, które nie zawiera metaznaków, jest równoważne ze stringami.SplitN.

Przykład:

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

Liczba określa liczbę zwracanych podciągów:

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
źródło
3
to wygląda na
przesadę
@Tom Ale to wciąż interesujące, nawet jeśli nie jest to najlepsza odpowiedź tutaj. Głosowałem za tą odpowiedzią, ponieważ czegoś się nauczyłem.
Denys Séguret
Należy pamiętać, że Fields()nie zwróci pustych ciągów. Więc liczba zwróconych pól będzie się różnić. Jeśli próbujesz przeanalizować coś spójnego, to nie zadziała. Może być konieczne użycie wyrażenia regularnego, jeśli FieldsFunc()również nie zadziała.
Tom
3

Wymyśliłem następujące, ale wydaje się to zbyt szczegółowe:

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

który oceni jako:

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

Czy istnieje bardziej zwięzłe lub idiomatyczne wyrażenie?

ralfoide
źródło