我正在使用Package regexp查找Golang中的所有mactch子串,但得到了意外的结果.以下是我的代码:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    str := "build: xxxxxx Prefix:middle#6\nPrefix:middle#16026Prefix:middle#1111\n Prefix:middle#110 Prefix:middle.#2 Prefix:middl.e#111 Prefix:middle#112"
    regexpStr := "\\bPrefix:([a-zA-Z0-9]+[\\w-.]+[^.])#[0-9]+"
    re := regexp.MustCompile(regexpStr)
    matchs := re.FindAllString(str, -1)
    fmt.Println(matchs)
}

你可以在https://go.dev/play/p/XFSMW09MKxV分钟内看到它.

预期:

[Prefix:middle#6 Prefix:middle#110 Prefix:middl.e#111 Prefix:middle#112]

但我得到了:

[Prefix:middle#6 Prefix:middle#16026 Prefix:middle#110 Prefix:middl.e#111 Prefix:middle#112]

为什么是Prefix:middle#16026个人?有人能告诉我原因吗?以及如何修复它,谢谢.

以下是应该匹配的规则:

我想从String中抽出Prefix:${middle}#${number}美元.

  • ${middle}条规则:

    • 允许的字符:字母、数字、下划线、下划线、圆点
    • 必须以字母或数字开头
    • 不能以点结尾
  • ${number}条规则:

    • 应该是数字
  • Prefix:${middle}#${number}可以出现在字符串的开头或结尾,也可以出现在字符串中间,但:

    • 出现在字符串的开头,则需要后跟空格或/n
    • 出现在字符串末尾,则需要在其前面加一个空格或/n
    • 位于字符串中间,但它的前面和后面都需要换行符或空格.

推荐答案

您可以对regexp.FindAllStringSubmatch使用以下正则表达式:

(?:\s|^)(Prefix:[a-zA-Z0-9][\w.-]*[^.]#\d+)(?:\s|$)

请看regex demo.

Note,因为空格边界(?:\s|^)(?:\s|$)都是consuming个模式,所以此模式仅在字符串中的空格加倍后才起作用,并且会阻止连续匹配.因此,在运行上面的正则表达式之前,应该使用regexp.MustCompile(\s).ReplaceAllString(str, "$0$0")或类似的代码.

Details:

  • (?:\s|^)-空格或字符串开头
  • (Prefix:[a-zA-Z0-9][\w.-]*[^.]#\d+) - Group 1:
    • Prefix:-固定字符串
    • [a-zA-Z0-9]-字母数字
    • [\w.-]*-零个或更多字母、数字、下划线、圆点或连字符
    • [^.]-.以外的字符
    • #-#个字符
    • \d+-一个或多个数字
  • (?:\s|$)-空格或字符串结尾

请参阅Go demo:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    str := "Prefix:middle#113 build: xxxxxx Prefix:middle#6\nPrefix:middle#16026Prefix:middle#1111\n Prefix:middle#110 Prefix:middle.#2 Prefix:middl.e#111 Prefix:middle#112"
    re := regexp.MustCompile(`(?:\s|^)(Prefix:[a-zA-Z0-9][\w.-]*[^.]#\d+)(?:\s|$)`)
    matchs := re.FindAllStringSubmatch(regexp.MustCompile(`\s`).ReplaceAllString(str, "$0$0"), -1)
    for _, m := range matchs {
        fmt.Println(m[1])
    }
}

输出:

Prefix:middle#113
Prefix:middle#6
Prefix:middle#110
Prefix:middl.e#111
Prefix:middle#112

Go相关问答推荐

我不能让GIO画一个按钮

Go协议缓冲区导入问题

如何预编译Golang标准库?

在GO中创建[]字符串类型的变量

GO框架Echo中间件的使用

从使用Golang otelmux检测的Otel跟踪中获取trace_id

Redis:尽管数据存在,但 rdb.Pipelined 中出现redis:nil错误

从文件读取字节,将其保存到 struct 体并修改值

在多个 struct 体中重用 Go 中的函数

当我使用 CircleCI 构建 Go Image 时,我得到runtime/cgo: pthread_create failed: Operation not allowed

使用 httptest 对 http 请求进行单元测试重试

如何将已知类型转换为指向switch 中类型参数的指针?

是否可以在调试期间在 VSCode 中预览 github.com/shopspring/decimal 值?

Golang 创建一个带有处理程序的模拟数据库并使用接口调用数据库

golang yaml 马歇尔网址

从数据库中带有 imageurl 的文件夹中获取图像,并在我的浏览器中用 golang 中的 echo 显示

如何将多个切片打印为一个切片?

在我的情况下,如何以正确的方式测试方法?

GoLang 遍历 yaml 文件

Go 1.18 泛型如何使用接口定义新的类型参数