Go by Example

String Functions

The strings package - searching, splitting, trimming, replacing, and building strings efficiently with strings.Builder.

The strings package provides utility functions for searching, splitting, joining, trimming, and transforming strings. For efficient string construction in loops, strings.Builder avoids the O(n²) cost of repeated concatenation.

Search and test string content with Contains, HasPrefix, HasSuffix, Count, and Index.

package main
 
import (
    "fmt"
    "strings"
)
 
func main() {
    s := "Hello, Go World"
 
    fmt.Println(strings.Contains(s, "Go"))      // true
    fmt.Println(strings.HasPrefix(s, "Hello"))  // true
    fmt.Println(strings.HasSuffix(s, "World"))  // true
    fmt.Println(strings.Count(s, "o"))          // 3
    fmt.Println(strings.Index(s, "Go"))         // 7
}

Split strings into parts and rejoin them with Join. Replace one or all occurrences with Replace and ReplaceAll.

package main
 
import (
    "fmt"
    "strings"
)
 
func main() {
    csv := "one,two,three"
    parts := strings.Split(csv, ",")
    fmt.Println(parts)                          // [one two three]
    fmt.Println(strings.Join(parts, " | "))     // one | two | three
 
    s := "aababc"
    fmt.Println(strings.Replace(s, "a", "x", 2))  // xxbabc (first 2 only)
    fmt.Println(strings.ReplaceAll(s, "a", "x"))   // xxbxbc
}

Convert case and trim whitespace or specific characters. Repeat a string N times.

package main
 
import (
    "fmt"
    "strings"
)
 
func main() {
    fmt.Println(strings.ToUpper("hello")) // HELLO
    fmt.Println(strings.ToLower("HELLO")) // hello
 
    padded := "  hello  "
    fmt.Println(strings.TrimSpace(padded))      // "hello"
    fmt.Println(strings.Trim(padded, " "))       // "hello"
    fmt.Println(strings.TrimLeft(padded, " "))   // "hello  "
    fmt.Println(strings.TrimRight(padded, " "))  // "  hello"
 
    fmt.Println(strings.Repeat("ab", 3)) // ababab
}

Use strings.Builder to build strings efficiently in a loop. It avoids allocating a new string on every append.

package main
 
import (
    "fmt"
    "strings"
)
 
func join(words []string, sep string) string {
    var b strings.Builder
    for i, w := range words {
        if i > 0 {
            b.WriteString(sep)
        }
        b.WriteString(w)
    }
    return b.String()
}
 
func main() {
    result := join([]string{"foo", "bar", "baz"}, ", ")
    fmt.Println(result) // foo, bar, baz
}

In production

strings.Builder is the correct way to build strings in a loop - it writes to an internal byte buffer and converts once at the end. Repeated + concatenation inside a loop creates a new string allocation per iteration: O(n²) total work and GC pressure. strings.Title is deprecated - use golang.org/x/text/cases for locale-aware title casing, since strings.Title does not handle Unicode correctly. For contains/prefix/suffix checks on byte slices rather than strings, use the bytes package equivalents to avoid an allocation.

Enjoyed this? Get more essays on software craft delivered to your inbox.

Subscribe free