Following up on my previous question about using Golang's regex to replace between strings. I now have a bit of complexity added to it. Here is what the contexts of my file looks like:
foo:
blahblah
MYSTRING=*
bar:
blah
blah
MYSTRING=*
I need to replace what's between MYSTRING=
and with a string of my choice (like previous stated in the original post). I can do that with:
var re = regexp.MustCompile(`(MYSTRING=).*`)
s := re.ReplaceAllString(content, `${1}stringofmychoice`)
But now I need to match and replace only after a certain occurrence. So that the contents of my file can look something like this:
foo:
blahblah
MYSTRING=foostring
bar:
blah
blah
MYSTRING=barstring
ReplaceAllString
obviously replaces everything, which is not what I want. Is there a way to only match and replace the first occurrence after a certain string?
For a bit of background about all of this. I'm trying to write a program to edit the contents of a given docker-compose.yml
file and its environment variables. I need to edit the environment variable MYSTRING
differently depending on what service it's listed under. In the example above, the two different services would be foo
and bar
.
You may use ReplaceAllStringFunc
and use a regex like
(?m)^bar:(?:
\s{4}.*)+
See the regex demo. It will match a bar
block indented with four whitespaces. Then, after a match is obtained, you may use a regular ReplaceAllString
on the match.
See the Go demo:
package main
import (
"fmt"
"regexp"
)
const sample = `foo:
blahblah
MYSTRING=*
bar:
blah
blah
MYSTRING=*`
func main() {
re := regexp.MustCompile(`(?m)^bar:(?:
\s{4}.*)+`)
re_2 := regexp.MustCompile(`(MYSTRING=).*`)
s := re.ReplaceAllStringFunc(sample, func(m string) string {
return re_2.ReplaceAllString(m, `${1}stringofmychoice`)
})
fmt.Println(s)
}
Here, the second occurrence is changed in the bar
block:
foo:
blahblah
MYSTRING=*
bar:
blah
blah
MYSTRING=stringofmychoice