我希望使用正则表达式将以下字符串解析为map[string]string
:
time="2017-05-30T19:02:08-05:00" level=info msg="some log message" app=sample size=10
我试图制作一张有
的地图m["time"] = "2017-05-30T19:02:08-05:00"
m["level"] = "info"
等
我尝试使用regex.FindAllStringIndex
但是不能提出合适的正则表达式吗?这是正确的方法吗?
答案 0 :(得分:4)
您可以简单地使用github.com/kr/logfmt
package。
Package实现了logfmt键值对的解码。
示例logfmt消息:
foo=bar a=14 baz="hello kitty" cool%story=bro f %^asdf
JSON中的示例结果:
{ "foo": "bar", "a": 14, "baz": "hello kitty", "cool%story": "bro", "f": true, "%^asdf": true }
答案 1 :(得分:4)
这不是使用正则表达式,而只是使用strings.FieldsFunc如何实现相同的示例。
https://play.golang.org/p/rr6U8xTJZT
package main
import (
"fmt"
"strings"
"unicode"
)
const foo = `time="2017-05-30T19:02:08-05:00" level=info msg="some log message" app=sample size=10`
func main() {
lastQuote := rune(0)
f := func(c rune) bool {
switch {
case c == lastQuote:
lastQuote = rune(0)
return false
case lastQuote != rune(0):
return false
case unicode.In(c, unicode.Quotation_Mark):
lastQuote = c
return false
default:
return unicode.IsSpace(c)
}
}
// splitting string by space but considering quoted section
items := strings.FieldsFunc(foo, f)
// create and fill the map
m := make(map[string]string)
for _, item := range items {
x := strings.Split(item, "=")
m[x[0]] = x[1]
}
// print the map
for k, v := range m {
fmt.Printf("%s: %s\n", k, v)
}
}
答案 2 :(得分:1)
在正则表达式和FindStringSubmatch和SubexpNames函数中使用命名捕获组。 E.g:
s := `time="2017-05-30T19:02:08-05:00" level=info msg="some log message" app=sample size=10`
re := regexp.MustCompile(`time="(?P<time>.*?)"\slevel=(?P<level>.*?)\s`)
values := re.FindStringSubmatch(s)
keys := re.SubexpNames()
// create map
d := make(map[string]string)
for i := 1; i < len(keys); i++ {
d[keys[i]] = values[i]
}
fmt.Println(d)
// OUTPUT: map[time:2017-05-30T19:02:08-05:00 level:info]
values
是包含所有子匹配的列表。第一个子匹配是与正则表达式匹配的整个表达式,后跟每个捕获组的子匹配。
如果您需要更频繁地将代码包装到函数中(例如,如果您需要像pythons match.groupdict
这样的东西),则可以将代码包装到函数中:
package main
import (
"fmt"
"regexp"
)
func groupmap(s string, r *regexp.Regexp) map[string]string {
values := r.FindStringSubmatch(s)
keys := r.SubexpNames()
// create map
d := make(map[string]string)
for i := 1; i < len(keys); i++ {
d[keys[i]] = values[i]
}
return d
}
func main() {
s := `time="2017-05-30T19:02:08-05:00" level=info msg="some log message" app=sample size=10`
re := regexp.MustCompile(`time="(?P<time>.*?)"\slevel=(?P<level>.*?)\s`)
fmt.Println(groupmap(s, re))
// OUTPUT: map[time:2017-05-30T19:02:08-05:00 level:info]
}