Golang regex:忽略多次出现

gab*_*gab 2 regex go

我有一个简单的需求。给出此输入(字符串):10 20 30 40 65 45 44 67 100 200 65 40 66 88 65

我需要获取 65 到 66 之间的所有数字。问题是当每个限制多次出现时。使用像 (65).+(66) 这样的正则表达式,我捕获了 65 45 44 67 100 200 65 40 66。但我只想得到 40。

我怎样才能做到这一点?

https://regex101.com/r/9HoKxr/1

Jvd*_*vdV 5

听起来您想排除模式编号中匹配的“65”,直到第一次出现“66”?这有点冗长,但是:

\b65((?:\s(?:\d|[1-57-9]\d|6[0-47-9]|\d{3,}))+?)\s66\b
Run Code Online (Sandbox Code Playgroud)

查看在线演示


  • \b65\s- 在单词边界和空白字符之间以“65”开头;
  • (- 打开捕获组;
    • (?:\s- 具有空白字符常量的非捕获组;
    • (?:\d|[1-57-9]\d|6[0-46-9]|\d{3,})- 嵌套非捕获组匹配除“65”或“66”之外的任何整数;
    • )+?)- 关闭非捕获组并至少匹配一次但尽可能少的次数。然后关闭捕获组;
  • \s66\b- 匹配另一个空格,后跟“66”和单词边界。

笔记:

  • Trim()我们将通过 strings 包使用函数处理前导空格;
  • 在我的示例中,我使用了“10 20 30 40 65 45 44 40 66 200 65 40 66 88 65”,它应该返回多个匹配项。在这种情况下,OP 正在寻找“最短”的匹配子字符串;
  • “最短”意味着当子字符串用空格分割时我们正在寻找最少数量的元素(使用上面提到的字符串包中的“Fields”函数)。因此,“123456”优先于“1 2 3”,尽管就字符而言是“更长”的子字符串;

尝试:

package main

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

func main() {
    s := `10 20 30 40 65 45 44 40 66 200 65 40 66 88 65`
    re := regexp.MustCompile(`\b65((?:\s(?:\d|[1-57-9]\d|6[0-47-9]|\d{3,}))+?)\s66\b`)
    matches := re.FindAllStringSubmatch(s, -1) // Retrieve all matches

    shortest := ``
    for i, _ := range matches { // Loop over array
        if shortest == `` || len(strings.Fields(matches[i][1])) < len(strings.Fields(shortest)) {
            shortest = strings.Trim(matches[i][1], ` `)
        }
    }
    fmt.Println(shortest)
}
Run Code Online (Sandbox Code Playgroud)

在这里亲自尝试一下。