我在试着找一种围棋的方法来匹配regexp.Regexp的图案.

以下是比赛的标准:

  1. 它必须匹配FooBar或它的子串Foo在行的开头,或者根本不匹配.
  2. 如果在#1中匹配,则任一匹配项后面必须有其他字符(即\S+)

因此,它应该匹配,例如:

  • 比赛:FooABC
  • 比赛:FooBarABC
  • 不匹配:FooBar(因为后面没有其他字符)
  • 不匹配:ABC(因为它不是以Foo开头)

我试了各种表达方式,但似乎就是想不通.

我发现在其他实现中有负面的先行模式,但Go似乎不提供它.有没有其他办法来解决这个问题?

见(更新版):https://regex101.com/r/SWSTzv/3

EDIT:我知道,这显然可以在不使用regexp的情况下得到解决.然而,这个请求的目的是了解这个问题是否可以通过Go的stdlib实现来解决.

推荐答案

为什么不直接反转与正则表达式^Foo(?:Bar)?$匹配的结果(好的,不仅仅是)?

package main

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

func main() {
  re := regexp.MustCompile(`^Foo(?:Bar)?$`)
  str := `Foo
FooBar
FooA
FooB
FooBa
FooBax
FooBxr
FooBarAbc
FooBarFoo
ABC
AbcFooBar`

  for _, s := range strings.Split(str, "\n") {
    if strings.HasPrefix(s, "Foo") && !re.MatchString(s) {
      fmt.Println(s)
    }
  }
}

输出:

FooA
FooB
FooBa
FooBax
FooBxr
FooBarAbc
FooBarFoo

试穿一下rextester号.

Update
更多地基于正则表达式并使用the trick的解决方案.

package main

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

func main() {
  re := regexp.MustCompile(`^Foo$|^FooBar$|^(Foo.+)`)
  str := `Foo
FooBar
FooA
FooB
FooBa
FooBax
FooBxr
FooBarAbc
FooBarFoo
ABC
AbcFooBar`

  for _, s := range strings.Split(str, "\n") {
    submatches := re.FindStringSubmatch(s)
    if submatches != nil && submatches[1] != "" {
      fmt.Println(submatches[1])
    }
  }
}

试穿一下rextester号.

Go相关问答推荐

如何在另一个文件夹中使用Delve运行二进制文件?

为什么 `go mod` 占用了另一个磁盘上的空间而不是我的 GOPATH?

正则表达式模式,确保至少一个字符与其他条件一起存在

我们如何保证取消的上下文会导致 goroutine 终止?

如何根据地址和大小打印字符串

为什么 net/http 不遵守超过 30 秒的超时持续时间?

使用 Go Colly 抓取所有可能的标签并将它们放入一个变量中

go - 仅在函数即将返回错误时清理资源

Apache Beam 左加入 Go

使用图像解码 JPEG 时 colored颜色 不正确.解码并写入 PDF?

枚举的 Golang 验证器自定义验证规则

在恒等函数中将类型 T 转换为类型 U

具有未导出字段的 struct 类型之间的转换

每次有人进入我的网站时如何运行特定功能?

具有近似约束的函数值导致的实例化失败

Golang Echo Labstack 如何在模板视图中调用函数/方法

GRPC 反向代理混淆 GRPC 和 GRPC-Web

Grafana/Prometheus 将多个 ip 可视化为查询

为什么 Go 中的 maps.Keys() 将 map 类型指定为 M?

手动下载并放置一个 golang mod 文件