英文:
Regular expression to capture a group that is optionally present in Go
问题
我正在尝试编写一个正则表达式,用于在表示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
替换为FooBar
的第一个字段的类型。我尝试将[]
设为可选项,如下所示:
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
}
这里出了什么问题?(我可以使用两个不同的正则表达式进行两次处理,但我更希望一次完成)。
英文:
I'm trying to write a regular expression that in a string representing Go code will replace the name of a type, say Bar
, with an updated name, say FooBar
, but only where it appears as the type of a field in another struct or as an array of that type. So I'd like to convert for example
type Foo struct {
Bar Bar
Baz []Bar
Bars []Bar
}
into
type Foo struct {
Bar FooBar
Baz []FooBar
Bars []FooBar
}
So far, I've managed to convert the array field types using this 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`))
}
which produces
type Foo struct {
Bar Bar
Baz []FooBar
Bars []FooBar
}
The replacement of Bar
is missing as the type of the first field, also named Bar
. I've tried making the []
optional like so,
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`))
}
But this produces an output where all of the field types are missing:
type Foo struct {
Bar
Baz
Bars
}
What is wrong here? (I could use a two-pass approach with two different regular expressions, but I would prefer to achieve this in one go).
答案1
得分: 2
根据你的情况,gofmt
可能是一个更好的选择:
gofmt -r 'Bar -> FooBar' hello.go
文件 hello.go
package hello
type Foo struct {
FooBar FooBar
Baz []FooBar
Bars []FooBar
}
英文:
Depending on your situation, gofmt
might be a better option:
gofmt -r 'Bar -> FooBar' hello.go
File hello.go
package hello
type Foo struct {
FooBar FooBar
Baz []FooBar
Bars []FooBar
}
答案2
得分: 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$2FooBar`))
}
这将产生期望的结果
type Foo struct {
Bar FooBar
Baz []FooBar
Bars []FooBar
}
英文:
It turns out the third reference needs to be ${3}
, not $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$2FooBar`))
}
which produces the desired result
type Foo struct {
Bar FooBar
Baz []FooBar
Bars []FooBar
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论