Golang正则表达式命名组和子匹配项

Ran*_*man 5 regex go

我试图匹配一个正则表达式,并获取匹配的捕获组名称。当正则表达式仅与字符串匹配一次,但如果它与字符串匹配一次以上,SubexpNames则不返回重复的名称,则此方法有效。

这是一个例子:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("(?P<first>[a-zA-Z]+) ")
    fmt.Printf("%q\n", re.SubexpNames())
    fmt.Printf("%q\n", re.FindAllStringSubmatch("Alan Turing ", -1))
}
Run Code Online (Sandbox Code Playgroud)

输出为:

["" "first"]
[["Alan " "Alan"] ["Turing " "Turing"]]
Run Code Online (Sandbox Code Playgroud)

是否可以获取每个子匹配项的捕获组名称?

Von*_*onC 9

这可能会包含在 Go 1.14 中(2020 年第一季度,尚未确认)。
请参阅“提案:正则表达式:添加(*Regexp).SubexpIndex#32420 ”。更新:它已包含在 Go 1.15(2020 年 8 月)的提交 782fcb4中。

// SubexpIndex returns the index of the first subexpression with the given name,
// or else -1 if there is no subexpression with that name.
//
// Note that multiple subexpressions can be written using the same name, as in
// (?P<bob>a+)(?P<bob>b+), which declares two subexpressions named "bob".
// In this case SubexpIndex returns the index of the leftmost such subexpression
// in the regular expression.
func (*Regexp) SubexpIndex(name string) int
Run Code Online (Sandbox Code Playgroud)

这在CL 187919中进行了讨论。

re := regexp.MustCompile(`(?P<first>[a-zA-Z]+) (?P<last>[a-zA-Z]+)`)
fmt.Println(re.MatchString("Alan Turing"))
matches := re.FindStringSubmatch("Alan Turing")
lastIndex := re.SubexpIndex("last")
fmt.Printf("last => %d\n", lastIndex)
fmt.Println(matches[lastIndex])

// Output:
// true
// last => 2
// Turing
Run Code Online (Sandbox Code Playgroud)


ale*_*asi 5

组名和位置是固定的:

re := regexp.MustCompile("(?P<first>[a-zA-Z]+) ")
groupNames := re.SubexpNames()
for matchNum, match := range re.FindAllStringSubmatch("Alan Turing ", -1) {
    for groupIdx, group := range match {
        name := groupNames[groupIdx]
        if name == "" {
            name = "*"
        }
        fmt.Printf("#%d text: '%s', group: '%s'\n", matchNum, group, name)
    }
}
Run Code Online (Sandbox Code Playgroud)