Golang Regexp命名组和子匹配

时间:2016-01-22 14:55:15

标签: 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))
}

输出结果为:

["" "first"]
[["Alan " "Alan"] ["Turing " "Turing"]]

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

2 个答案:

答案 0 :(得分:2)

群组名称和职位是固定的:

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)
    }
}

答案 1 :(得分:1)

这可能包含在Go 1.14中(2020年第一季度,尚未确认)。
参见“ proposal: regexp: add (*Regexp).SubexpIndex #32420

import graphene
from graphene import relay
from graphene_sqlalchemy import SQLAlchemyObjectType, SQLAlchemyConnectionField
from .models import User as UserModel


class User(SQLAlchemyObjectType):
    class Meta:
        model = UserModel
        interfaces = (relay.Node, )

class UserConnection(relay.Connection):
    class Meta:
        node = User

class Query(graphene.ObjectType):
    node = relay.Node.Field()

    search_users = SQLAlchemyConnectionField(UserConnection, q=graphene.String())
    def resolve_all_users(self, info, **args):
        q = args.get("q")
        users_query = User.get_query(info)
        # For now I've just copied sort implementation from UnsortedSQLAlchemyConnectionField
        # I didn't find a better way to re-use this code without duplicating it :-(
        if 'sort' in args:
            sort = args['sort']
            if isinstance(sort, str):
                users_query = users_query.order_by(sort.value)
            else:
                users_query = users_query.order_by(*(col.value for col in sort))
        users = users_query.filter(UserModel.email.contains(q)).all()
        return users

目前在CL 187919

中对此进行了考虑
// 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