在Go中捕获可选存在的组的正则表达式。

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

Regular expression to capture a group that is optionally present in Go

问题

我正在尝试编写一个正则表达式,用于在表示Go代码的字符串中将类型名称(例如Bar)替换为更新后的名称(例如FooBar),但仅在它作为另一个结构体字段的类型或该类型的数组时才替换。因此,我想将以下代码:

  1. type Foo struct {
  2. Bar Bar
  3. Baz []Bar
  4. Bars []Bar
  5. }

转换为:

  1. type Foo struct {
  2. Bar FooBar
  3. Baz []FooBar
  4. Bars []FooBar
  5. }

到目前为止,我已经成功使用ReplaceAllString将数组字段类型进行了转换:

  1. package main
  2. import (
  3. "fmt"
  4. "regexp"
  5. )
  6. func main() {
  7. re := regexp.MustCompile(`(\w+)(\s+)\[\]Bar`)
  8. s := `type Foo struct {
  9. Bar Bar
  10. Baz []Bar
  11. Bars []Bar
  12. }`
  13. fmt.Println(re.ReplaceAllString(s, `$1$2[]FooBar`))
  14. }

这将产生以下输出:

  1. type Foo struct {
  2. Bar Bar
  3. Baz []FooBar
  4. Bars []FooBar
  5. }

但是,缺少将Bar替换为FooBar的第一个字段的类型。我尝试将[]设为可选项,如下所示:

  1. package main
  2. import (
  3. "fmt"
  4. "regexp"
  5. )
  6. func main() {
  7. re := regexp.MustCompile(`(\w+)(\s+)(\[\])?Bar`)
  8. s := `type Foo struct {
  9. Bar Bar
  10. Baz []Bar
  11. Bars []Bar
  12. }`
  13. fmt.Println(re.ReplaceAllString(s, `$1$2$3FooBar`))
  14. }

但是,这会导致所有字段类型都丢失的输出:

  1. type Foo struct {
  2. Bar
  3. Baz
  4. Bars
  5. }

这里出了什么问题?(我可以使用两个不同的正则表达式进行两次处理,但我更希望一次完成)。

英文:

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

  1. type Foo struct {
  2. Bar Bar
  3. Baz []Bar
  4. Bars []Bar
  5. }

into

  1. type Foo struct {
  2. Bar FooBar
  3. Baz []FooBar
  4. Bars []FooBar
  5. }

So far, I've managed to convert the array field types using this ReplaceAllString:

  1. package main
  2. import (
  3. "fmt"
  4. "regexp"
  5. )
  6. func main() {
  7. re := regexp.MustCompile(`(\w+)(\s+)\[\]Bar`)
  8. s := `type Foo struct {
  9. Bar Bar
  10. Baz []Bar
  11. Bars []Bar
  12. }`
  13. fmt.Println(re.ReplaceAllString(s, `$1$2[]FooBar`))
  14. }

which produces

  1. type Foo struct {
  2. Bar Bar
  3. Baz []FooBar
  4. Bars []FooBar
  5. }

The replacement of Bar is missing as the type of the first field, also named Bar. I've tried making the [] optional like so,

  1. package main
  2. import (
  3. "fmt"
  4. "regexp"
  5. )
  6. func main() {
  7. re := regexp.MustCompile(`(\w+)(\s+)(\[\])?Bar`)
  8. s := `type Foo struct {
  9. Bar Bar
  10. Baz []Bar
  11. Bars []Bar
  12. }`
  13. fmt.Println(re.ReplaceAllString(s, `$1$2$3FooBar`))
  14. }

But this produces an output where all of the field types are missing:

  1. type Foo struct {
  2. Bar
  3. Baz
  4. Bars
  5. }

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可能是一个更好的选择:

  1. gofmt -r 'Bar -> FooBar' hello.go
  1. package hello
  2. type Foo struct {
  3. FooBar FooBar
  4. Baz []FooBar
  5. Bars []FooBar
  6. }

https://godocs.io/cmd/gofmt

英文:

Depending on your situation, gofmt might be a better option:

  1. gofmt -r 'Bar -> FooBar' hello.go
  1. package hello
  2. type Foo struct {
  3. FooBar FooBar
  4. Baz []FooBar
  5. Bars []FooBar
  6. }

https://godocs.io/cmd/gofmt

答案2

得分: 1

原文翻译如下:

原来第三个引用需要${3},而不是$3

  1. package main
  2. import (
  3. "fmt"
  4. "regexp"
  5. )
  6. func main() {
  7. re := regexp.MustCompile(`(\w+)(\s+)(\[\])?Bar`)
  8. s := `type Foo struct {
  9. Bar Bar
  10. Baz []Bar
  11. Bars []Bar
  12. }`
  13. fmt.Println(re.ReplaceAllString(s, `$1$2FooBar`))
  14. }

这将产生期望的结果

  1. type Foo struct {
  2. Bar FooBar
  3. Baz []FooBar
  4. Bars []FooBar
  5. }
英文:

It turns out the third reference needs to be ${3}, not $3:

  1. package main
  2. import (
  3. "fmt"
  4. "regexp"
  5. )
  6. func main() {
  7. re := regexp.MustCompile(`(\w+)(\s+)(\[\])?Bar`)
  8. s := `type Foo struct {
  9. Bar Bar
  10. Baz []Bar
  11. Bars []Bar
  12. }`
  13. fmt.Println(re.ReplaceAllString(s, `$1$2FooBar`))
  14. }

which produces the desired result

  1. type Foo struct {
  2. Bar FooBar
  3. Baz []FooBar
  4. Bars []FooBar
  5. }

huangapple
  • 本文由 发表于 2023年1月15日 00:15:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75119361.html
匿名

发表评论

匿名网友

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

确定