具有FindAllStringSubmatch的Golang复杂正则表达式

时间:2018-10-09 16:07:02

标签: regex go

我有一个 superheroes 字符串,其中全部具有 name ,但是并非全部属性。

它的格式为UTF8Encoding utf8 = new UTF8Encoding(); string utf8Encoded = HttpUtility.UrlEncode(msg,utf8);,其中⛦name⛯attrName☾attrData☽是可选的。

因此,超级英雄字符串为:

attrName☾attrData☽

我想使用Regex提取字符串,然后将结果填充到地图切片中,例如:

⛦superman⛯shirt☾blue☽⛦joker⛯⛦spiderman⛯age☾15yo☽girlFriend☾Cindy☽

我无法在Go操场上完成它。我使用正则表达式[ {name: superman, shirt: blue}, {name: joker}, {name: spiderman, age: 15yo, girlFriend: Cindy} ] ,但它只能捕获单个属性,即正则表达式无法捕获⛦(\\w+)⛯(?:(\\w+)☾(\\w+)☽)*属性。

我的代码是:

age

Go Playground代码在此处:https://play.golang.org/p/Epv66LVwuRK

运行结果为:

func main() {
    re := regexp.MustCompile("⛦(\\w+)⛯(?:(\\w+)☾(\\w+)☽)*")
    fmt.Printf("%q\n", re.FindAllStringSubmatch("⛦superman⛯shirt☾blue☽⛦joker⛯⛦spiderman⛯age☾15yo☽girlFriend☾Cindy☽", -1))
}

[ ["⛦superman⛯shirt☾blue☽" "superman" "shirt" "blue"] ["⛦joker⛯" "joker" "" ""] ["⛦spiderman⛯age☾15yo☽girlFriend☾Cindy☽" "spiderman" "girlFriend" "Cindy"] ] 丢失了,知道吗?

2 个答案:

答案 0 :(得分:2)

您不能使用单个捕获组捕获任意数量的子字符串。您需要先匹配整个记录,然后再将其子部分与另一个正则表达式匹配。

查看示例:

package main

import (
    "fmt"
    "regexp"
)

func main() {

    str := "⛦superman⛯shirt☾blue☽⛦joker⛯⛦spiderman⛯age☾15yo☽girlFriend☾Cindy☽"

    re_main := regexp.MustCompile(`⛦(\w+)⛯((?:\w+☾\w+☽)*)`)
    re_aux := regexp.MustCompile(`(\w+)☾(\w+)☽`)
    for _, match := range re_main.FindAllStringSubmatch(str, -1) {
        fmt.Printf("%v\n", match[1])
        for _, match_aux := range re_aux.FindAllStringSubmatch(match[2], -1) {      
            fmt.Printf("%v: %v\n", match_aux[1], match_aux[2])
        }
        fmt.Println("--END OF MATCH--") 
    }  
}

请参见Go demo

输出:

superman
shirt: blue
--END OF MATCH--
joker
--END OF MATCH--
spiderman
age: 15yo
girlFriend: Cindy
--END OF MATCH--

在这里,⛦(\w+)⛯((?:\w+☾\w+☽)*)是将主“键”匹配并捕获到组1中的主正则表达式,而其他键值的字符串则捕获到组2中。然后,您需要遍历找到的匹配,并使用(\w+)☾(\w+)☽从第2组中收集所有键值。

答案 1 :(得分:1)

您已将regex设置为⛦(\\w+)⛯(?:(\\w+)☾(\\w+)☽)*,如keyvalue只打印两个级别,就像按regex一样打印:

[["⛦superman⛯shirt☾blue☽" "superman" "shirt" "blue"]
["⛦joker⛯" "joker" "" ""]
["⛦spiderman⛯age☾15yo☽girl☾Cindy☽" "spiderman" "girl" "Cindy"]]

我再增加一对正则表达式keyvalue,并打印age值,请遵循以下regex的代码:

re := regexp.MustCompile("⛦(\\w+)⛯(?:(\\w+)☾(\\w+)☽)*(?:(\\w+)☾(\\w+)☽)*")
    fmt.Printf("%q\n", re.FindAllStringSubmatch("⛦superman⛯shirt☾blue☽⛦joker⛯⛦spiderman⛯age☾15yo☽girl☾Cindy☽", -1))