Розділити рядок на пробіли в Go?


115

З огляду на такий рядок введення, як " word1 word2 word3 word4 ", що було б найкращим підходом розділити це як масив рядків у Go? Зауважте, що між кожним словом може бути будь-яка кількість пробілів або символів, розташованих між унікодом.

На Яві я б просто користувався someString.trim().split("\\s+").

(Примітка: можливий повторюваний рядок розділення за допомогою регулярного вираження в Go не дає відповіді хорошої якості. Будь ласка, надайте фактичний приклад, а не лише посилання на посилання на regexpабо stringsпакети.)

Відповіді:


248

У stringsпакеті є Fieldsметод.

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

З документів:

func Fields(s string) []string

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


1
На жаль, strings.Fieldsне ігнорує пробіли в цитованих частинах.
chmike

@chmike Щоправда, але в момент, коли цитати вплутуються, ви займаєтесь розшифровкою чи аналізом певного кодування чи формату .
mtraceur

@chmike може знадобитися shlexдля цього godoc.org/github.com/google/shlex
akhy

8

Якщо ви використовуєте пораду: regexp.Split

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

Розділяє фрагменти s на підрядки, розділені виразом, і повертає фрагмент підрядок між цими збігами виразів.

Зріз, повернутий цим методом, складається з усіх підрядків s, що не містяться у зрізі, поверненому FindAllString. Коли викликається вираз, який не містить метахарактерів, він еквівалентний рядкам.SplitN.

Приклад:

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

Кількість визначає кількість підрядів, які потрібно повернути:

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

3
це здається надмірним
вт

@Tom Але це все ще цікаво, навіть якщо це не найкраща відповідь тут. Я відповів на цю відповідь, бо чогось навчився.
Denys Séguret

Слід зазначити, що Fields()порожні рядки не повертаються. Тож кількість повернених полів буде змінюватися. Якщо ви намагаєтесь розібрати щось послідовне, то це не вийде. Можливо, вам знадобиться використовувати регулярний вираз, якщо FieldsFunc()також не буде працювати.
Том

3

Я придумав наступне, але це здається занадто багатослівним:

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

який оцінюватиме:

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

Чи є більш компактний чи ідіоматичний вираз?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.