Комплексное регулярное выражение Голанга с FindAllStringSubmatch - PullRequest
0 голосов
/ 09 октября 2018

У меня есть супергерои строка, все из них имеют имя с, но не все из них имеют атрибуты.

Он имеет формат ⛦name⛯attrName☾attrData☽, где attrName☾attrData☽ является необязательным.

Итак, строка superheroes :

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

Я хочу использовать Regex для извлечения строки и заполняет результат в фрагмент карты , например:

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

Я не могу это сделатьна игровой площадке Go.Я использую регулярное выражение ⛦(\\w+)⛯(?:(\\w+)☾(\\w+)☽)*, но оно может захватывать только один атрибут, то есть регулярное выражение не может захватить атрибуты age.

Мой код:

func main() {
    re := regexp.MustCompile("⛦(\\w+)⛯(?:(\\w+)☾(\\w+)☽)*")
    fmt.Printf("%q\n", 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 отсутствует, есть идеи?

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Вы не можете захватить произвольное количество подстрок с помощью одной группы захвата.Сначала необходимо сопоставить всю запись, а затем сопоставить ее части с другим регулярным выражением.

См. Пример:

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

Вывод:

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

Здесь ⛦(\w+)⛯((?:\w+☾\w+☽)*) - это основное регулярное выражение, которое сопоставляет и фиксирует в Группе 1 главный «ключ», а строка других значений ключа фиксируется в Группе.2. Затем вам нужно перебрать найденные совпадения и собрать все значения ключей из группы 2, используя (\w+)☾(\w+)☽.

0 голосов
/ 09 октября 2018

Вы установили regex как ⛦(\\w+)⛯(?:(\\w+)☾(\\w+)☽)*, который печатает только два уровня key и value, как будто он печатает согласно вашим regex:

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

Я увеличиваюregex еще одна пара key и value, и она также печатает значение 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...