Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace Nth occurrence of string in golang

Tags:

string

go

How do I replace the nth (in this case second) occurrence of a string in golang? The following code replaces the example string optimismo from optimism with o from optimism when I want it to be optimismo from

package main

import (
    "fmt"
    "strings"
)

func main() {
    mystring := "optimismo from optimism"
    excludingSecond := strings.Replace(mystring, "optimism", "", 1)
    fmt.Println(excludingSecond)
}
like image 372
AppTest Avatar asked May 23 '17 20:05

AppTest


3 Answers

For anyone stumbling on this post and is looking to replace the LAST occurrence

package main

import (
    "fmt"
    "strings"
)

func main() {
    mystring := "optimismo from optimism"

    i := strings.LastIndex(mystring, "optimism")
    excludingLast := mystring[:i] + strings.Replace(mystring[i:], "optimism", "", 1)
    fmt.Println(excludingLast)
}
like image 122
Akshar Avatar answered Nov 03 '22 12:11

Akshar


For example,

package main

import (
    "fmt"
    "strings"
)

// Replace the nth occurrence of old in s by new.
func replaceNth(s, old, new string, n int) string {
    i := 0
    for m := 1; m <= n; m++ {
        x := strings.Index(s[i:], old)
        if x < 0 {
            break
        }
        i += x
        if m == n {
            return s[:i] + new + s[i+len(old):]
        }
        i += len(old)
    }
    return s
}

func main() {
    s := "optimismo from optimism"
    fmt.Printf("%q\n", s)
    t := replaceNth(s, "optimism", "", 2)
    fmt.Printf("%q\n", t)
}

Output:

"optimismo from optimism"
"optimismo from "
like image 23
peterSO Avatar answered Nov 03 '22 10:11

peterSO


If you always know there will be two, you could use https://godoc.org/strings#Index to find the index of the first, then do the replace on everything after, finally combining them together.

https://play.golang.org/p/CeJFViNjgH

func main() {
    search := "optimism"
    mystring := "optimismo from optimism"

    // find index of the first and add the length to get the end of the word
    ind := strings.Index(mystring, search)
    if ind == -1 {
        fmt.Println("doesn't exist")
        return // error case
    }
    ind += len(search)

    excludingSecond := mystring[:ind]

    // run replace on everything after the first one
    excludingSecond += strings.Replace(mystring[ind:], search, "", 1)
    fmt.Println(excludingSecond)
}
like image 3
RayfenWindspear Avatar answered Nov 03 '22 11:11

RayfenWindspear