If you are searching for golang split string, golang string split, strings split golang, or go split string, the core API is strings.Split from the standard library. Go stores text as UTF-8; splitting follows the rules in package strings. When I put this guide together I ran each listing with go run on Go 1.22 (Linux) so the printed slices here match what you should see locally.
Tested on: Go 1.22 on 64-bit Linux; program listings were executed with the stock
gotoolchain while this page was revised.
Quick answer: use
strings.Split(s, sep). It returns a[]stringof the parts between each non-overlapping instance ofsep.
package main
import (
"fmt"
"strings"
)
func main() {
text := "red,green,blue"
parts := strings.Split(text, ",")
fmt.Println(parts)
}Output:
[red green blue]Split a String in Go Using strings.Split
Basic strings.Split example
strings.Split(s, sep string) []string returns subslices of s separated by sep. The separator is not included in the elements (unless you switch to SplitAfter).
Split a string by comma, space, or custom separator
Use any non-empty string as sep: comma, |, a multi-character delimiter, and so on. If sep is not in s, you get a one-element slice holding the whole string (see mistakes).
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%q\n", strings.Split("a|b|c", "|"))
fmt.Printf("%q\n", strings.Split("one two", " "))
}Split a String by Whitespace
Use strings.Fields for spaces, tabs, and newlines
Many tutorials start with strings.Split(text, " "). That only splits on a single ASCII space, so double spaces create empty strings. For real whitespace (spaces, tabs, newlines), strings.Fields is usually what you want: it splits on runs of characters for which unicode.IsSpace is true, trims leading and trailing space, and merges internal gaps.
package main
import (
"fmt"
"strings"
)
func main() {
text := " go linux\tcloud\nexample "
words := strings.Fields(text)
fmt.Println(words)
}Output:
[go linux cloud example]Split a String into Limited Parts
Use strings.SplitN to limit the number of results
strings.SplitN is documented to return at most n substrings when n > 0; the last element holds anything that was not split yet. That fits values like name=value-with=equals or key=value.
package main
import (
"fmt"
"strings"
)
func main() {
text := "name=golinuxcloud=linux"
parts := strings.SplitN(text, "=", 2)
fmt.Println(parts)
}Output:
[name golinuxcloud=linux]The official docs also steer you toward strings.Cut when you only need the first separator.
Split only at the first separator using strings.Cut
strings.Cut splits s at the first instance of sep, returning before, after, and found. There is no slice allocation for the two-part case.
package main
import (
"fmt"
"strings"
)
func main() {
text := "USER=deepak"
key, value, found := strings.Cut(text, "=")
fmt.Println("found:", found)
fmt.Println("key:", key)
fmt.Println("value:", value)
}Output:
found: true
key: USER
value: deepakSplit and Clean the Result
Remove empty values after splitting
After Split, you may want to drop empty strings (for example from trailing commas).
package main
import (
"fmt"
"strings"
)
func main() {
text := "go,,linux,,cloud"
raw := strings.Split(text, ",")
var cleaned []string
for _, item := range raw {
if item != "" {
cleaned = append(cleaned, item)
}
}
fmt.Println(cleaned)
}Output:
[go linux cloud]Trim spaces from split values
package main
import (
"fmt"
"strings"
)
func main() {
text := "go, linux, cloud"
raw := strings.Split(text, ",")
for i, item := range raw {
raw[i] = strings.TrimSpace(item)
}
fmt.Println(raw)
}Output:
[go linux cloud]To join again, use strings.Join.
Split Strings in Common Scenarios
Split CSV-like comma-separated values
For a simple line with no quoted commas, Split is fine:
line := "alice,bob,carol"
cols := strings.Split(line, ",")Split file paths, URLs, and key-value pairs
pathname := "/var/log/nginx/access.log"
segments := strings.Split(pathname, "/") // leading "/" produces an empty first element
u := "https://example.com:8443/v1/api"
scheme, rest, ok := strings.Cut(u, "://")
hostPort, pathOnly, _ := strings.Cut(rest, "/")
kv := "theme=dark"
key, val, _ := strings.Cut(kv, "=")For real path logic, path/filepath is often safer than manual splitting.
Split environment variables like PATH
PATH uses the OS list separator; on Unix it is :. Split on that rune as a string:
pathEnv := "/usr/bin:/bin"
dirs := strings.Split(pathEnv, ":")On Windows, use filepath.SplitList so you respect the platform separator.
Split host:port-like strings
addr := "db.internal:5432"
host, port, ok := strings.Cut(addr, ":")Split command output into lines
out := "line one\nline two\n"
lines := strings.Split(strings.TrimSuffix(out, "\n"), "\n")Or use bufio.Scanner for streaming.
Split log lines into fields
Use Fields when columns are whitespace-separated; use Split or SplitN when you have a fixed delimiter.
Split file extensions or path-like strings
strings.Split("archive.tar.gz", ".") yields ["archive", "tar", "gz"]. If you only care about the suffix after the last dot, strings.LastIndex or path/filepath.Ext is usually clearer than splitting the whole name.
Split only the first separator
Prefer Cut for two-part splits; use SplitN(..., 2) when you specifically want a slice with the remainder in the last slot.
strings.Split vs Related Functions
strings.Split vs strings.SplitN
Split keeps splitting until the end. SplitN stops after n-1 separators so you get at most n pieces.
package main
import (
"fmt"
"strings"
)
func main() {
s := "a,b,c,d"
fmt.Printf("%q\n", strings.Split(s, ","))
fmt.Printf("%q\n", strings.SplitN(s, ",", 3))
}Output:
["a" "b" "c" "d"]
["a" "b" "c,d"]strings.Split vs strings.Fields
Split uses an exact sep string. Fields uses Unicode space rules and never emits empty tokens between spaces.
package main
import (
"fmt"
"strings"
)
func main() {
s := " hello world "
fmt.Printf("%q\n", strings.Split(s, " "))
fmt.Printf("%q\n", strings.Fields(s))
}Output:
["" "" "hello" "" "" "world" "" ""]
["hello" "world"]strings.Split vs strings.Cut
Cut handles only the first separator and returns two strings plus found. Split always returns a slice and scans the whole string.
package main
import (
"fmt"
"strings"
)
func main() {
s := "key=value=extra"
before, after, ok := strings.Cut(s, "=")
fmt.Println("Cut:", before, after, ok)
fmt.Printf("%q\n", strings.Split(s, "="))
}Output:
Cut: key value=extra true
["key" "value" "extra"]strings.Split vs regexp.Split
regexp.Split cuts where a pattern matches—for example multiple spaces or mixed delimiters. The n parameter behaves as documented: negative means no limit, zero returns nil, positive caps substrings with the rest in the last element.
package main
import (
"fmt"
"regexp"
"strings"
)
func main() {
s := " hello world "
re := regexp.MustCompile(`\s+`)
fmt.Printf("%q\n", strings.Split(s, " "))
fmt.Printf("%q\n", re.Split(s, -1))
}Output:
["" "" "hello" "" "" "world" "" ""]
["" "hello" "world" ""]When the delimiter is fixed text, strings.Split is simpler and faster than compiling a regex.
strings.FieldsFunc
strings.FieldsFunc sits between plain Fields and a regex: split where a function of rune returns true (for example “any digit”).
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
s := "a1b2c3"
fmt.Printf("%q\n", strings.FieldsFunc(s, unicode.IsDigit))
}Output:
["a" "b" "c"]strings.SplitAfter
strings.SplitAfter keeps the separator on the left segment, which helps when the delimiter is part of the field text you want to preserve.
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%q\n", strings.SplitAfter("red,green,", ","))
}Output:
["red," "green," ""]Common Mistakes with strings.Split
Separator not found returns a slice with one item
package main
import (
"fmt"
"strings"
)
func main() {
parts := strings.Split("golinuxcloud", ",")
fmt.Println(parts)
fmt.Println(len(parts))
}Output:
[golinuxcloud]
1Split does not return an empty slice when the separator is missing; you get the original string as the only element.
Empty separator splits by UTF-8 sequence
package main
import (
"fmt"
"strings"
)
func main() {
parts := strings.Split("go", "")
fmt.Println(parts)
}Output:
[g o]strings.Split is not a CSV parser
This looks tempting:
line := `alice,"linux,cloud",admin`
parts := strings.Split(line, ",")Quoted commas break the model. For real CSV, use encoding/csv with a Reader.
Go String Split Cheat Sheet
Which split function should you use?
| Goal | Use | Example |
|---|---|---|
| Split by comma or custom separator | strings.Split |
strings.Split(s, ",") |
| Split by whitespace | strings.Fields |
strings.Fields(s) |
| Split into limited parts | strings.SplitN |
strings.SplitN(s, ":", 2) |
| Split only once | strings.Cut |
before, after, found := strings.Cut(s, "=") |
| Keep separator after each part | strings.SplitAfter |
strings.SplitAfter(s, ",") |
| Split using regex | regexp.Split |
re.Split(s, -1) |
| Trim spaces after split | strings.TrimSpace |
Per element in a loop |
| Join split values again | strings.Join |
strings.Join(parts, ",") |
References
- Package strings (
Split,SplitN,Cut,Fields,Join) - Package regexp
- Package encoding/csv

