如何匹配golang中所有重叠的模式?

时间:2018-12-27 08:51:45

标签: regex go

我想在以下字符串中获取以下模式(\.\.#\.\.)的索引:

...#...#....#.....#..#..#..#.......

但是Golang不管理重叠匹配。

因此我得到了[[1 6 1 6] [10 15 10 15] [16 21 16 21] [22 27 22 27]]

正如人们所看到的,第二个.在两个点#的前面和后缀,但是方法FindAllStringSubmatchIndex并没有返回。

我尝试使用与regexp不同的方法,但未成功。在搜索文档时,我发现https://golang.org/pkg/regexphttps://golang.org/src/regexp/regexp.go

上没有任何用处

相反,似乎regexp本身不支持此功能:

  

//如果存在'All',则例程匹配整个表达式的连续不重叠匹配。

我可以解决问题,但是由于我正在练习此语言来学习Golang,所以我想知道。谢谢:)

这是我的参考代码:

        matches := r.pattern.FindAllStringSubmatchIndex(startingState)
        fmt.Println(r.pattern)
        fmt.Println(matches)
        for _, m := range matches {
            tempState = tempState[:m[0]+2] + "#" + tempState[m[0]+3:]
            fmt.Println(tempState)
        }

2 个答案:

答案 0 :(得分:4)

没有理由为此使用正则表达式。正则表达式对于这样一个简单的任务来说过于矫kill过正-它过于复杂且效率较低。相反,您应该只使用strings.Index和for循环:

input := "...#...#....#.....#..#..#..#......."
idx := []int{}
j := 0
for {
    i := strings.Index(input[j:], "..#..")
    if i == -1 {
        break
    }
    fmt.Println(j)
    idx = append(idx, j+i)
    j += i+1
}
fmt.Println("Indexes:", idx)

Playground link

答案 1 :(得分:3)

Go适用于程序员。例如,

package main

import (
    "fmt"
    "strings"
)

func findIndices(haystack, needle string) []int {
    var x []int
    for i := 0; i < len(haystack)-len(needle); i++ {
        j := strings.Index(haystack[i:], needle)
        if j < 0 {
            break
        }
        i += j
        x = append(x, i)
    }
    return x
}

func main() {
    haystack := `...#...#....#.....#..#..#..#.......`
    needle := `..#..`
    fmt.Println(findIndices(haystack, needle))
}

游乐场:https://play.golang.org/p/nNE5IB1feQT

输出:

[1 5 10 16 19 22 25]

正则表达式参考:

Regular Expression Matching Can Be Simple And Fast

Implementing Regular Expressions

Package [regexp/]syntax