用于捕获 Go 中可选存在的组的正则表达式?

分享于2023年02月01日 go regex 问答
【问题标题】:Regular expression to capture a group that is optionally present in Go?用于捕获 Go 中可选存在的组的正则表达式?
【发布时间】:2023-01-15 00:26:13
【问题描述】:

我正在尝试编写一个正则表达式,在表示 Go 代码的字符串中将替换类型的名称,例如 Bar ,更新后的名称,例如 FooBar ,但仅在它显示为字段类型的地方在另一个结构中或作为该类型的数组。所以我想转换例如

type Foo struct {
    Bar  Bar
    Baz  []Bar
    Bars []Bar
}

进入

type Foo struct {
    Bar  FooBar
    Baz  []FooBar
    Bars []FooBar
}

到目前为止,我已经成功地使用这个 ReplaceAllString 转换数组字段类型:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`(\w+)(\s+)\[\]Bar`)

    s := `type Foo struct {
    Bar  Bar
    Baz  []Bar
    Bars []Bar
}`

    fmt.Println(re.ReplaceAllString(s, `$1$2[]FooBar`))
}

产生

type Foo struct {
    Bar  Bar
    Baz  []FooBar
    Bars []FooBar
}

缺少的是将 Bar 替换为第一个字段的类型,也命名为 Bar 。我试过像这样将 [] 设为可选,

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`(\w+)(\s+)(\[\])?Bar`)

    s := `type Foo struct {
    Bar  Bar
    Baz  []Bar
    Bars []Bar
}`

    fmt.Println(re.ReplaceAllString(s, `$1$2$3FooBar`))
}

但这会产生一个缺少所有字段类型的输出:

type Foo struct {
    Bar  
    Baz  
    Bars 
}

有人可以发现这里有什么问题吗? (我可以对两个不同的正则表达式使用两次传递的方法,但更愿意一次完成)。


【解决方案1】:

结果第三个引用需要是 ${3} ,而不是 $3

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`(w+)(s+)([])?Bar`)

    s := `type Foo struct {
    Bar  Bar
    Baz  []Bar
    Bars []Bar
}`

    fmt.Println(re.ReplaceAllString(s, `$1$2${3}FooBar`))
}

产生预期的结果

type Foo struct {
    Bar  FooBar
    Baz  []FooBar
    Bars []FooBar
}

【讨论】: