Splitting a string into pieces
To break a string into parts, Go uses functions from the strings package. strings.Split(s, sep) cuts s at every occurrence of the separator sep and returns the pieces as a slice of strings, []string. The separator itself is not included in the pieces.
sentence := "hello world foo"
words := strings.Split(sentence, " ")
fmt.Println(words) // [hello world foo]
fmt.Println(len(words)) // 3
The result is a slice, so you can index it, loop over it with range, and ask for its length with len. Here words[0] is "hello" and words[2] is "foo".
Exercise step by step
- Start from the given variable.
sentenceholds"hello world foo". - Declare
wordswith:=. Its type,[]string, is taken from the value on the right. - Call
strings.Split(sentence, " "). The separator is a single space, written as a string in double quotes.
The solution in Go
sentence := "hello world foo"
words := strings.Split(sentence, " ")
Afterwards, words is a slice with three elements: "hello", "world" and "foo".
Split against Fields
strings.Split follows the separator literally. That is exactly what you want for a fixed delimiter such as a comma, but it behaves unexpectedly when the text has extra spaces. Compare it with strings.Fields(s), which splits around runs of whitespace of any kind (spaces, tabs, newlines) and ignores whitespace at the start and end:
fmt.Printf("%q\n", strings.Split("a b", " ")) // ["a" "" "b"]
fmt.Printf("%q\n", strings.Fields(" a b ")) // ["a" "b"]
With two spaces between the letters, Split finds an empty piece between them, because there is nothing between the two separators. Fields never returns empty strings. Use Fields to split text into words, and Split when the separator carries meaning, as in the comma-separated line below:
parts := strings.Split("a,b,c", ",")
fmt.Printf("%q\n", parts) // ["a" "b" "c"]
Edge cases
- Empty input.
strings.Split("", " ")returns a slice with one element, the empty string, and so has length 1.strings.Fields("")returns an empty slice. - Separator not found. If the separator never appears,
Splitreturns a slice holding the whole original string as its only element. - Leading and trailing separators. They produce empty strings at the ends of the result.
Splitkeeps them, andFieldsdrops them. - The separator is a string. It can be longer than one character, as in
strings.Split(s, ", "). An empty separator splits the string into its individual characters. - Limiting the pieces.
strings.SplitN(s, sep, n)returns at mostnpieces, with the rest of the text left in the last one.
Common mistakes
- Using single quotes.
' 'is a rune, not a string, sostrings.Split(sentence, ' ')does not compile. The separator needs double quotes. - Expecting a method.
sentence.Split(" ")doesn't exist. Strings have no methods, and the function takes the string as its first argument. - Forgetting the import. The file must import
"strings", or the compiler reportsundefined: strings. - Assuming a fixed length. Reading
words[2]panics when the split gives fewer than three pieces. Checklen(words)first.
Using the pieces
A split is usually the first step of a larger job. Once you have the slice, loop over it with range, which gives the position and the piece on each turn. A line such as "name=Ada" becomes two parts with strings.Split(line, "="), and then kv[0] is the key and kv[1] is the value. Each piece is an ordinary string, so you can trim it, change its case or convert it to a number afterwards.
Splitting never changes the original string. The pieces are new values, and sentence is still "hello world foo" after the call. The opposite operation is strings.Join(words, " "), which glues a slice of strings back into one string with a separator between the elements.
Notice also that the number of pieces is always one more than the number of separators found, which is why a string with no separator comes back as a single piece.
Key takeaways
strings.Split(s, sep)returns a[]stringand removes the separator.- Consecutive separators produce empty strings;
strings.Fieldsavoids them for whitespace. - The separator must be a string in double quotes, not a rune.