Fractionner une chaîne sur des espaces dans Go?

115

Étant donné une chaîne d'entrée telle que " word1 word2 word3 word4 ", quelle serait la meilleure approche pour diviser cela en un tableau de chaînes dans Go? Notez qu'il peut y avoir n'importe quel nombre d'espaces ou de caractères d'espacement Unicode entre chaque mot.

En Java, je voudrais simplement utiliser someString.trim().split("\\s+").

(Remarque: une éventuelle chaîne de fractionnement en double utilisant une expression régulière dans Go ne donne pas de réponse de bonne qualité. Veuillez fournir un exemple réel, pas seulement un lien vers la référence regexpou stringspackages.)

ralfoide
la source

Réponses:

248

Le stringspackage a une Fieldsméthode.

someString := "one    two   three four "

words := strings.Fields(someString)

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

DÉMO: http://play.golang.org/p/et97S90cIH

À partir de la documentation:

func Fields(s string) []string

Fields divise la chaîne sautour de chaque instance d'un ou plusieurs caractères d'espace blanc consécutifs, renvoyant un tableau de sous-chaînes de sou une liste vide si s contient uniquement un espace blanc.

Je déteste paresseux
la source
1
Malheureusement, strings.Fieldsn'ignore pas les espaces dans les parties entre guillemets.
chmike
@chmike C'est vrai, mais au moment où les citations sont impliquées, vous êtes en train de décoder ou d' analyser un encodage ou un format spécifique .
mtraceur le
@chmike dont vous pourriez avoir besoin shlexpour ce godoc.org/github.com/google/shlex
akhy le
8

Si vous utilisez tip: regexp.Split

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

Divise les tranches s en sous-chaînes séparées par l'expression et renvoie une tranche des sous-chaînes entre ces correspondances d'expression.

La tranche retournée par cette méthode comprend toutes les sous-chaînes de s non contenues dans la tranche retournée par FindAllString. Lorsqu'il est appelé sur une expression qui ne contient aucun méta-caractère, il équivaut à strings.SplitN.

Exemple:

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

Le nombre détermine le nombre de sous-chaînes à renvoyer:

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
la source
3
cela semble exagéré
thwd
@Tom Mais c'est quand même intéressant même si ce n'est pas la meilleure réponse ici. J'ai voté pour cette réponse parce que j'ai appris quelque chose.
Denys Séguret
Vous devriez noter que Fields()ne retournera pas de chaînes vides. Le nombre de champs renvoyés variera donc. Si vous essayez d'analyser quelque chose de cohérent, cela ne fonctionnera pas pour vous. Vous devrez peut-être utiliser regex si un FieldsFunc()ne fonctionne pas non plus.
Tom
3

J'ai proposé ce qui suit, mais cela semble un peu trop détaillé:

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

qui évaluera à:

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

Existe-t-il une expression plus compacte ou plus idiomatique?

ralfoide
la source