Golang正则表达式匹配并替换某个字符串后的第一个匹配项

Golang正则表达式匹配并替换某个字符串后的第一个匹配项

问题描述:

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.

紧随我之前的有关使用Golang的正则表达式替换字符串之间的问题。 现在,我增加了一些复杂性。 这是我文件的上下文: p>

  foo:
 blahblah 
 MYSTRING = * 
bar:
 blah 
 blah 
 MYSTRING = * \  n  code>  pre> 
 
 

我需要用我选择的字符串替换 MYSTRING = code>和 code>之间的内容(例如上一个 在原始帖子中说明)。 我可以这样: p>

  var re = regexp.MustCompile(`(MYSTRING =)。*`)
s:= re.ReplaceAllString(content,`$ {1  } stringofmychoice`)
  code>  pre> 
 
 

但是现在我只需要匹配并替换就可以了。 这样我的文件内容就可以像这样: p>

  foo:
 blahblah 
 MYSTRING = foostring 
bar:
 blah 
 blah 
 MYSTRING =  barstring 
  code>  pre> 
 
 

ReplaceAllString code>显然替换了所有内容,这不是我想要的。 有没有办法只匹配并替换某个字符串后的第一个匹配项? p>


有关所有这些的一些背景知识。 我正在尝试编写一个程序来编辑给定 docker-compose.yml code>文件及其环境变量的内容。 我需要根据下面列出的服务来不同地编辑环境变量 MYSTRING code>。 在上面的示例中,两个不同的服务将是 foo code>和 bar code>。 p> div>

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