The strings package provides functions for reading, searching, and rewriting UTF-8 encoded strings, plus Builder, Reader, and Replacer types for the cases where a plain string won't do.
Examples
Grows one internal buffer instead of allocating a new string on every += concatenation, the standard fix once a loop is building a string piece by piece.
var b strings.Builder
for _, task := range []string{"write the handler", "test it", "ship it"} {
b.WriteString("- ")
b.WriteString(task)
b.WriteByte('\n')
}
fmt.Print(b.String())- write the handler
- test it
- ship itReports whether a substring appears anywhere in s, the most common string check in everyday code.
strings.Contains("seafood", "foo")
strings.Contains("seafood", "bar")true
falseReplaceAll swaps every occurrence of old for new. Replace, its more general form, takes a count to cap how many replacements happen.
strings.ReplaceAll("2026-08-15", "-", "/")2026/08/15Split breaks a string into a slice on every occurrence of a separator; Join does the reverse. The pair behind most CSV-style parsing.
csv := "go,rust,python"
langs := strings.Split(csv, ",")
fmt.Println(langs)
fmt.Println(strings.Join(langs, " | "))[go rust python]
go | rust | pythonRemoves leading and trailing whitespace, including newlines, the first thing to reach for on anything read from a form, a file, or user input.
input := " go@example.com \n"
fmt.Printf("%q\n", strings.TrimSpace(input))"go@example.com"Normalizes case for comparisons, matching, or display. Both are Unicode-aware, not limited to ASCII.
strings.ToUpper("go")
strings.ToLower("GOPHER")GO
gopherChecks just the start or end of a string, cheaper and clearer than Contains when position matters, the shape behind most routing and file-extension checks.
path := "/api/v1/users"
strings.HasPrefix(path, "/api/")
strings.HasSuffix(path, ".json")true
false| Function | Description |
|---|---|
Clone(s) string | Returns a fresh copy of s that shares no memory with the original. |
Compare(a, b) int | Lexicographically compares two strings, returning -1, 0, or 1. |
Contains(s, substr) bool Contains("seafood", "foo") // true | Reports whether substr appears anywhere in s. |
Three functions cover different notions of "contains." | |
ContainsAny(s, chars) bool ContainsAny("seafood", "xyz") // false | Reports whether any character in chars appears in s. |
ContainsFunc(s, f) bool | Reports whether any rune in s satisfies f. |
ContainsRune(s, r) bool ContainsRune("seafood", 'f') // true | Reports whether rune r appears in s. |
Count(s, substr) int | Counts non-overlapping instances of substr in s. |
EqualFold(s, t) bool | Reports whether s and t are equal under Unicode case folding. |
HasPrefix(s, prefix) bool HasPrefix("golang", "go") // true | Reports whether s begins with prefix. |
HasSuffix(s, suffix) bool HasSuffix("golang", "lang") // true | Reports whether s ends with suffix. |
Index(s, substr) int Index("chicken", "ken") // 4 | Returns the index of substr's first occurrence, or -1 if absent. |
IndexAny(s, chars) int | Returns the index of the first char from chars found in s. |
IndexByte(s, c) int | Returns the index of the first occurrence of byte c. |
IndexFunc(s, f) int | Returns the index of the first rune satisfying f. |
IndexRune(s, r) int | Returns the index of the first occurrence of rune r. |
LastIndex(s, substr) int | Returns the index of substr's last occurrence, or -1 if absent. |
LastIndexAny(s, chars) int | Returns the index of the last char from chars found in s. |
LastIndexByte(s, c) int | Returns the index of the last occurrence of byte c. |
LastIndexFunc(s, f) int | Returns the index of the last rune satisfying f. |
Cut(s, sep) (before, after, found) Cut("key=value", "=") // "key", "value", true | Splits s at the first instance of sep, returning both sides and whether sep was found. |
Added in Go 1.18 to replace the older | |
CutPrefix(s, prefix) (after, found) | Removes prefix from s if present, reporting whether it was found. |
CutSuffix(s, suffix) (before, found) | Removes suffix from s if present, reporting whether it was found. |
Fields(s) []string Fields(" a b ") // [a b] | Splits s around runs of whitespace, discarding empty fields. |
FieldsFunc(s, f) []string | Splits s at runs of runes satisfying f. |
FieldsFuncSeq(s, f) iter.Seq[string] | Like FieldsFunc, but returns a lazy iterator instead of a slice. |
FieldsSeq(s) iter.Seq[string] | Like Fields, but returns a lazy iterator instead of a slice. |
Join(elems, sep) string Join([]string{"a", "b"}, "-") // "a-b" | Concatenates elems, placing sep between each one. |
Lines(s) iter.Seq[string] | Iterates over lines of s, each including its trailing newline. |
Split(s, sep) []string Split("a,b,c", ",") // [a b c] | Splits s on every instance of sep. |
| |
SplitAfter(s, sep) []string | Like Split, but keeps sep attached to the end of each piece. |
SplitAfterN(s, sep, n) []string | Like SplitAfter, capped at n substrings. |
SplitAfterSeq(s, sep) iter.Seq[string] | Like SplitAfter, but returns a lazy iterator instead of a slice. |
SplitN(s, sep, n) []string | Like Split, capped at n substrings. |
SplitSeq(s, sep) iter.Seq[string] | Like Split, but returns a lazy iterator instead of a slice. |
Trim(s, cutset) string | Removes leading and trailing runes present in cutset. |
TrimFunc(s, f) string | Removes leading and trailing runes satisfying f. |
TrimLeft(s, cutset) string | Removes leading runes present in cutset. |
TrimLeftFunc(s, f) string | Removes leading runes satisfying f. |
TrimPrefix(s, prefix) string | Removes prefix from s if present; returns s unchanged otherwise. |
TrimRight(s, cutset) string | Removes trailing runes present in cutset. |
TrimRightFunc(s, f) string | Removes trailing runes satisfying f. |
TrimSpace(s) string TrimSpace(" hi ") // "hi" | Removes leading and trailing whitespace, per Unicode's definition. |
TrimSuffix(s, suffix) string | Removes suffix from s if present; returns s unchanged otherwise. |
Title(s) string | Deprecated. Capitalized first letter of each word; use golang.org/x/text/cases instead. |
ToLower(s) string ToLower("Go") // "go" | Maps every rune to lowercase. |
ToLowerSpecial(c, s) string | Lowercases s using a language-specific case mapping (e.g. Turkish). |
ToTitle(s) string | Maps every rune to its Unicode title case (stronger than uppercase for a few scripts). |
ToTitleSpecial(c, s) string | Title-cases s using a language-specific case mapping. |
ToUpper(s) string ToUpper("go") // "GO" | Maps every rune to uppercase. |
ToUpperSpecial(c, s) string | Uppercases s using a language-specific case mapping. |
Map(mapping, s) string | Rewrites s by passing every rune through mapping; dropping a rune returns a negative value from mapping. |
Repeat(s, count) string Repeat("ab", 3) // "ababab" | Returns s concatenated to itself count times. |
Replace(s, old, new, n) string Replace("aaaa", "a", "b", 2) // "bbaa" | Replaces the first n instances of old with new; n = -1 replaces all. |
ReplaceAll(s, old, new) string ReplaceAll("gopher", "o", "0") // "g0pher" | Replaces every instance of old with new. |
ToValidUTF8(s, replacement) string | Replaces each invalid UTF-8 byte sequence with replacement. |
type Builder | Accumulates bytes into one buffer, so a loop builds a string without reallocating on every step. Its zero value is ready to use. |
type Reader r := strings.NewReader("hello") | Reads from a string; implements io.Reader, io.Seeker, and io.RuneScanner. |
type Replacer r := strings.NewReplacer("a", "1", "b", "2") | Performs several replacements in one pass, and is safe for concurrent use. |
Cap() int | Returns the capacity of the builder's internal buffer. |
Grow(n) | Reserves room for at least n more bytes, avoiding future reallocations. |
Len() int | Returns the number of bytes accumulated so far. |
Reset() | Discards accumulated content, returning the builder to empty. |
String() string | Returns the accumulated bytes as a string, with no copy. |
Write(p) (int, error) | Appends bytes p; implements io.Writer. |
WriteByte(c) error | Appends a single byte c. |
WriteRune(r) (int, error) | Appends the UTF-8 encoding of rune r. |
WriteString(s) (int, error) | Appends the contents of s. |
A | |
NewReader(s) *Reader NewReader("hi") // *strings.Reader | Wraps s in a Reader implementing io.Reader and related interfaces. |
Read(b) (n, err) | Reads up to len(b) bytes into b; implements io.Reader. |
ReadAt(b, off) (n, err) | Reads bytes starting at offset off, without moving the read cursor. |
ReadByte() (byte, error) | Reads and returns the next byte. |
ReadRune() (ch, size, err) | Reads and returns the next UTF-8 rune and its byte width. |
Seek(offset, whence) (int64, error) | Moves the read cursor; implements io.Seeker. |
Size() int64 | Returns the original length of the underlying string. |
UnreadByte() error | Un-reads the last byte, so the next Read returns it again. |
UnreadRune() error | Un-reads the last rune read by ReadRune. |
WriteTo(w) (int64, error) | Writes all remaining bytes to w; implements io.WriterTo. |
NewReplacer(oldnew ...string) *Replacer | Builds a Replacer from alternating old, new string pairs, applied in one pass. |
Replace(s) string | Returns s with all pairs replaced simultaneously (Replacer method). |
WriteString(w, s) (n, err) | Writes the replaced output of s directly to w, without building an intermediate string (Replacer method). |
Use Builder instead of += concatenation in a loop, and Replacer over chained ReplaceAll calls when doing several replacements at once.