我有一个超级英雄字符串,他们都有名字s,但不是所有的都有属性。
它具有⛦name⛯attrName☾attrData☽
,其中attrName☾attrData☽
是可选的。
所以,超级英雄的字符串是:
⛦superman⛯shirt☾blue☽⛦joker⛯⛦spiderman⛯age☾15yo☽girlFriend☾Cindy☽
我想使用正则表达式提取字符串,并将结果填充到地图切片中,如下所示:
[ {name: superman, shirt: blue},
{name: joker},
{name: spiderman, age: 15yo, girlFriend: Cindy} ]
我无法在围棋操场上完成它。我使用正则表达式⛦(\w+)⛯(?:(\w+)☾(\w+)☽)*
,但它只能捕获单个属性,即正则表达式无法捕获age
属性。
我的代码是:
func main() {
re := regexp.MustCompile("⛦(\w+)⛯(?:(\w+)☾(\w+)☽)*")
fmt.Printf("%qn", re.FindAllStringSubmatch("⛦superman⛯shirt☾blue☽⛦joker⛯⛦spiderman⛯age☾15yo☽girlFriend☾Cindy☽", -1))
}
Go Playground代码在这里:https://play.golang.org/p/Epv66LVwuRK
运行结果为:
[
["⛦superman⛯shirt☾blue☽" "superman" "shirt" "blue"]
["⛦joker⛯" "joker" "" ""]
["⛦spiderman⛯age☾15yo☽girlFriend☾Cindy☽" "spiderman" "girlFriend" "Cindy"]
]
age
不见了,知道吗?
不能使用单个捕获组捕获任意数量的子字符串。您需要先匹配整个记录,然后将其子部分与另一个正则表达式匹配。
请参阅示例:
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("%vn", match[1])
for _, match_aux := range re_aux.FindAllStringSubmatch(match[2], -1) {
fmt.Printf("%v: %vn", match_aux[1], match_aux[2])
}
fmt.Println("--END OF MATCH--")
}
}
查看 Go 演示
输出:
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 收集所有键值。
您已将regex
设置为⛦(\w+)⛯(?:(\w+)☾(\w+)☽)*
,它仅打印两级key
和value
,就像它根据您的regex
打印一样:
[["⛦superman⛯shirt☾blue☽" "superman" "shirt" "blue"]
["⛦joker⛯" "joker" "" ""]
["⛦spiderman⛯age☾15yo☽girl☾Cindy☽" "spiderman" "girl" "Cindy"]]
我将正则表达式再增加一个key
并value
对,它也打印age
值,请按照以下代码进行regex
:
re := regexp.MustCompile("⛦(\w+)⛯(?:(\w+)☾(\w+)☽)*(?:(\w+)☾(\w+)☽)*")
fmt.Printf("%qn", re.FindAllStringSubmatch("⛦superman⛯shirt☾blue☽⛦joker⛯⛦spiderman⛯age☾15yo☽girl☾Cindy☽", -1))