使用正则表达式替换一个出现的内容。

huangapple go评论101阅读模式
英文:

Replace one occurrence with regexp

问题

我想用正则表达式替换一个实例,而不是全部替换。我该如何使用Go的regexp库来实现这个功能?

输入:foobar1xfoobar2x
正则表达式:bar(.)x
替换:baz$1

ReplaceAllString输出:foobaz1foobaz2
ReplaceOneString输出:foobaz1foobar2x

英文:

I want to replace a only one instance with a regex rather than all of them. How would I do this with Go's regexp library?

input: foobar1xfoobar2x
regex: bar(.)x
replacement: baz$1

ReplaceAllString output: foobaz1foobaz2
ReplaceOneString output: foobaz1foobar2x

答案1

得分: 9

一般来说,如果你使用懒惰匹配并使用锚点来表示开头和结尾,你可以实现替换第一个匹配的行为:

使用 $1baz$2 替换 ^(.*?)bar(.*)$

示例:

package main

import (
	"fmt"
	"regexp"
)

func main() {
	src := "foobar1xfoobar2x"
	pat := regexp.MustCompile("^(.*?)bar(.*)$")
	repl := "baz$2"
	output := pat.ReplaceAllString(src, repl)
	fmt.Println(output)
}

输出

foobaz1xfoobar2x
英文:

In general, if you use lazy match and use anchors for beginning and end, you can have the replace first behavior:

replace `^(.*?)bar(.*)$` with `$1baz$2`.

Example:

package main

import (
	"fmt"
	"regexp"
)

func main() {
	src := "foobar1xfoobar2x"
	pat := regexp.MustCompile("^(.*?)bar(.*)$")
        repl := "baz$2"
	output := pat.ReplaceAllString(src, repl)
	fmt.Println(output)
}

Output

foobaz1xfoobar2x

答案2

得分: 6

我遇到了同样的问题。我想出了一个最简洁的解决方案:

package main

import (
    "fmt"
    "regexp"
    "strings"
)

func main() {
    re, _ := regexp.Compile("[a-z]{3}")
    s := "aaa bbb ccc"

    // 替换所有字符串
    fmt.Println(re.ReplaceAllString(s, "000"))

    // 替换一个字符串
    found := re.FindString(s)
    if found != "" {
        fmt.Println(strings.Replace(s, found, "000", 1))
    }
}

运行结果:

$ go run test.go 
000 000 000
000 bbb ccc
英文:

I had the same problem. The most clean solution I've come up with:

package main

import (
    "fmt"
	"regexp"
    "strings"
)

func main() {
    re, _ := regexp.Compile("[a-z]{3}")
    s := "aaa bbb ccc"

    // Replace all strings
    fmt.Println(re.ReplaceAllString(s, "000"))

    // Replace one string
    found := re.FindString(s)
    if found != "" {
        fmt.Println(strings.Replace(s, found, "000", 1))
    }
}

Running:

$ go run test.go 
000 000 000
000 bbb ccc

答案3

得分: 3

我无法使用已接受的解决方案,因为我的模式非常复杂。
最终我使用了ReplaceAllStringFunc:
https://play.golang.org/p/ihtuIU-WEYG

package main

import (
	"fmt"
	"regexp"
)

var pat = regexp.MustCompile("bar(.)(x)")

func main() {
	src := "foobar1xfoobar2x"
	flag := false
	output := pat.ReplaceAllStringFunc(src, func(a string) string {
		if flag {
			return a
		}
		flag = true
		return pat.ReplaceAllString(a, "baz$1$2")
	})
	fmt.Println(output)
}
英文:

I cound't use accepted solution because my pattern was very complicated.
I ended up with using ReplaceAllStringFunc :
https://play.golang.org/p/ihtuIU-WEYG

package main

import (
	"fmt"
	"regexp"
)

var pat = regexp.MustCompile("bar(.)(x)")

func main() {
	src := "foobar1xfoobar2x"
	flag := false
	output := pat.ReplaceAllStringFunc(src, func(a string) string {
		if flag {
			return a
		}
		flag = true
		return pat.ReplaceAllString(a, "baz$1$2")
	})
	fmt.Println(output)
}

huangapple
  • 本文由 发表于 2013年5月23日 07:57:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/16703501.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定