dongtiao1817
2018-10-09 16:07
采纳率: 100%
浏览 2.7k
已采纳

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

我有一个superheroes字符串,它们都有名字,但不是所有的都有属性。

它有一个格式为⛦Name⛯☾atta Data☽,其中attaName☾atta Data☽是可选的。

superheroes字符串如下:

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

我希望使用Regex提取字符串,并将结果填充到映射的一个片段中,如下所示:

[ {name: superman, shirt: blue},
  {name: joker},
  {name: spiderman, age: 15yo, girlFriend: Cindy} ]

我在Go上做不到。然后我又使用regex⛦(\w+)⛯(?:(\W+)☾(\w+)☽),但它只能捕获单个属性,即无法捕获年龄属性的regex。

我的代码:

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

Go代码在这里:https://play.golang.org/p/Epv66LVwuRK

运行结果如下:

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

age消失了,哪里出错了?

图片转代码服务由CSDN问答提供 功能建议

我有一个 superheroes 字符串,其中所有 名称,但其中不是全部具有属性。

其格式为⛦name⛯attrName☾attrData code ,其中attrName☾attrData☽是可选的。

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

⛦超人⛯衬衫☾蓝色☽⛦小丑⛯⛦蜘蛛侠⛯age☾15yo☽girlFriend☾Cindy☽

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

  [{名称:超人,衬衫:蓝色 },
 {name:joker},
 {name:Spiderman,年龄:15yo,girlFriend:Cindy}] 
   
 
 

我无法完成 在操场上。 我使用正则表达式⛦(\\ w +)⛯(?:(\\ w +)☾(\\ w +)☽)* ,但它只能捕获单个属性,即regex无法捕获 age 属性。

我的代码是:

  func main(){
 re:= regexp  .MustCompile(“⛦(\\ w +)⛯(?:(\\ w +)☾(\\ w +)☽)*”)
 fmt.Printf(“%q 
”,re.FindAllStringSubmatch(“⛦超人 ⛯shirt☾blue☽⛦小丑⛯⛦spiderman☾age☾15yo☽girlFriend☾Cindy☽“,-1))
} 
   
 
 

Go Playground代码为 在这里: https://play.golang.org/p/Epv66LVwuRK

运行结果为:

  [
 [“⛦superman⛯shirt☾blue☽”“ superman”“ shirt”“ blue”] \  n [“⛦joker⛯”“ joker”“”“”] 
 [“⛦蜘蛛侠⛯age☾15yo☽girlFriend☾Cindy☽”“ spiderman”“ girlFriend”“ Cindy”] 
] 
    
 
 

缺少 age ,知道吗?

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dsaff82024 2018-10-09 18:46
    已采纳

    You cannot capture arbitrary number of substrings with a single capturing group. You need to match the whole record first, and then match the subparts of it with another regex.

    See an example:

    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
    ", match[1])
            for _, match_aux := range re_aux.FindAllStringSubmatch(match[2], -1) {      
                fmt.Printf("%v: %v
    ", match_aux[1], match_aux[2])
            }
            fmt.Println("--END OF MATCH--") 
        }  
    }
    

    See the Go demo

    Output:

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

    Here, ⛦(\w+)⛯((?:\w+☾\w+☽)*) is the main regex that matches and captures into Group 1 the main "key" and the string of the other key-values is captured into Group 2. Then, you need to iterate over the found matches, and collect all key-values from the Group 2 using (\w+)☾(\w+)☽.

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • dtgv52982 2018-10-09 16:37

    You have set your regex like ⛦(\\w+)⛯(?:(\\w+)☾(\\w+)☽)* which prints only two level of key and value, like it prints as per your regex:

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

    I increase the regex one more key and value pairs and it prints the age value as well, follow the below code for regex:

    re := regexp.MustCompile("⛦(\\w+)⛯(?:(\\w+)☾(\\w+)☽)*(?:(\\w+)☾(\\w+)☽)*")
        fmt.Printf("%q
    ", re.FindAllStringSubmatch("⛦superman⛯shirt☾blue☽⛦joker⛯⛦spiderman⛯age☾15yo☽girl☾Cindy☽", -1))
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题