Start learning free

LESSON 63 OF 338 · STRINGS I

String Replace in Go: strings.ReplaceAll

Lesson Read the full explanation

In Go, you can replace a substring using strings.ReplaceAll(), which replaces every occurrence of the old substring with the new one:

result := strings.ReplaceAll(sentence, "cats", "dogs")
// "cats" is the substring to find
// "dogs" is the replacement

Here is an example:

sentence := "I love cats"
result := strings.ReplaceAll(sentence, "cats", "dogs")
fmt.Println(result)  // "I love dogs"

Assignment
Follow the Coding Tutorial and replace "cats" with "dogs" in sentence!


Hint
Use strings.ReplaceAll(sentence, "cats", "dogs") and assign the result to result.

STEP 1 OF 1
    Ctrl + Enter to check

    GO · STRINGS I

    String Replace in Go, explained

    Replacing text

    strings.ReplaceAll(s, old, new) returns a copy of s in which every occurrence of old is replaced by new. The first argument is the text to work on, the second is the substring to find, and the third is what to put in its place.

    sentence := "I love cats"
    result := strings.ReplaceAll(sentence, "cats", "dogs")
    fmt.Println(result) // I love dogs
    

    The function lives in the strings package, so a Go file that uses it needs import "strings".

    Strings are immutable

    Go strings can't be changed in place, so ReplaceAll doesn't modify sentence. It builds a new string and returns it. You have to keep the return value, which is why the lesson stores it in a new variable. The original is unchanged:

    sentence := "I love cats"
    strings.ReplaceAll(sentence, "cats", "dogs") // result thrown away
    fmt.Println(sentence)                        // I love cats
    

    Writing a call like that, with its result discarded, is allowed for a function call, so it compiles and silently does nothing useful. Assign the result to a variable, or assign it back to sentence with = if you no longer need the old text.

    Exercise step by step

    1. Start from the given variable. sentence holds "I love cats".
    2. Declare result with :=. It gets the type string from the value on the right.
    3. Call strings.ReplaceAll(sentence, "cats", "dogs"). Search sentence for "cats" and replace it with "dogs".

    The solution in Go

    sentence := "I love cats"
    
    result := strings.ReplaceAll(sentence, "cats", "dogs")
    

    Afterwards, result is "I love dogs" and sentence is still "I love cats".

    Replacing only some matches

    When you want to limit the number of replacements, use strings.Replace(s, old, new, n). It replaces at most the first n matches, and a negative n means all of them, which makes ReplaceAll a shorthand for Replace with -1.

    s := "I love cats and cats"
    fmt.Println(strings.ReplaceAll(s, "cats", "dogs")) // I love dogs and dogs
    fmt.Println(strings.Replace(s, "cats", "dogs", 1)) // I love dogs and cats
    

    Gotchas

    • Case matters. Searching for "Cats" does not match "cats", and nothing is replaced.
    • No match is not an error. If old isn't in the string, you get back an unchanged copy of the text.
    • Matching is literal. The search text is not a pattern. A . or * in it means exactly that character. Patterns need the regexp package.
    • Matches don't overlap. Replacing "aa" in "aaa" finds one match, at the start, not two.
    • Argument order. The order is text, old, new. Swapping the last two replaces "dogs" with "cats", which does nothing here.
    • Replaced text can contain the old text. The function makes a single pass over the original, so the new text is not searched again.

    Deleting text with ReplaceAll

    An empty replacement removes the matches, which is the simplest way to delete a character or word from a string. Replacing a space with nothing squeezes all spaces out, and replacing a separator with nothing joins the pieces:

    fmt.Println(strings.ReplaceAll("a-b-c", "-", "")) // abc
    fmt.Println(strings.ReplaceAll("a b", " ", ""))   // ab
    

    Replacement is also a quick way to normalise text before you compare it. You can chain calls, passing the result of one into the next, for example to replace several different separators with one. Each call returns a new string, so the chain never touches the original, and the work grows with the length of the text and the number of matches. For a handful of fixed replacements on short strings that cost is negligible.

    Several replacements at once

    When you have more than one pair to replace, strings.NewReplacer takes the pairs as alternating old and new strings and returns a value with a Replace method. It makes a single pass over the text, so replaced text is never searched again:

    r := strings.NewReplacer("cats", "dogs", "love", "like")
    fmt.Println(r.Replace("I love cats")) // I like dogs
    

    For the lesson's single replacement, ReplaceAll is the right tool: it is shorter and does exactly what the exercise asks.

    Key takeaways

    • strings.ReplaceAll(s, old, new) returns a new string with every match replaced.
    • The original string never changes, so keep the returned value.
    • Use strings.Replace with a count to replace only the first few matches.
    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free