Je viens de python, donc je ne regarde probablement pas ça de la bonne façon. Je voudrais créer une expression rationnelle assez compliquée et pouvoir accéder aux champs correspondants par nom. Je n'arrive pas à trouver un bon exemple. Le plus proche que j'ai réussi à obtenir est la suivante:
package main
import (
"fmt"
"regexp"
)
var myExp = regexp.MustCompile(`(?P<first>\d+)\.(\d+).(?P<second>\d+)`)
func main() {
fmt.Printf("%+v", myExp.FindStringSubmatch("1234.5678.9"))
match := myExp.FindStringSubmatch("1234.5678.9")
for i, name := range myExp.SubexpNames() {
fmt.Printf("'%s'\t %d -> %s\n", name, i, match[i])
}
//fmt.Printf("by name: %s %s\n", match["first"], match["second"])
}
La ligne commentée est la façon dont je m'attendrais à accéder aux champs nommés en python. Quelle est la façon équivalente de le faire en aller? Ou si j'ai besoin de convertir le match en carte, quelle est la manière la plus idiomatique de créer et d’accéder ensuite à la carte?
Вы можете ссылаться на свои именованные группы захвата, используя map
следующим образом:
package main
import (
"fmt"
"regexp"
)
var myExp = regexp.MustCompile(`(?P<first>\d+)\.(\d+).(?P<second>\d+)`)
func main() {
match := myExp.FindStringSubmatch("1234.5678.9")
result := make(map[string]string)
for i, name := range myExp.SubexpNames() {
if i != 0 && name != "" {
result[name] = match[i]
}
}
fmt.Printf("by name: %s %s\n", result["first"], result["second"])
}
Je n'ai pas la réputation de commenter, alors pardonnez-moi si cela ne devrait pas être une "réponse", mais j'ai trouvé la réponse ci-dessus utile, je l'ai donc intégrée à une fonction:
func reSubMatchMap(r *regexp.Regexp, str string) (map[string]string) {
match := r.FindStringSubmatch(str)
subMatchMap := make(map[string]string)
for i, name := range r.SubexpNames() {
if i != 0 {
subMatchMap[name] = match[i]
}
}
return subMatchMap
}
Exemple d'utilisation sur le terrain de jeu: https://play.golang.org/p/LPLND6FnTXO
J'espère que cela sera utile à quelqu'un d'autre. Aimez la facilité des groupes de capture nommés dans Go.
Les autres approches génèrent une erreur lorsqu'aucune correspondance n'a été trouvée pour un "groupe nommé". Cependant, ce qui suit crée une map
avec tous les groupes nommés réellement trouvés:
func findNamedMatches(regex *regexp.Regexp, str string) map[string]string {
match := regex.FindStringSubmatch(remote)
results := map[string]string{}
for i, name := range match {
results[repoRegex.SubexpNames()[i]] = name
}
return results
}
Cette approche va seulement renvoyer la carte avec les correspondances du groupe nommé. S'il n'y a pas de correspondance, cela retournera simplement nil
. J'ai trouvé que c'était beaucoup plus facile à gérer que les erreurs commises si aucune correspondance n'était trouvée.