go语言json解析gjson
go语言json解析无论是使用标准库encoding/json还是第三库json-iterator,都需要定义 结构体或者map,有的时候我们只想获取json中的部分值,定义结构体或者map还是比较麻烦的, 这时候我们可以选择gjson。
gjson是一个Go包,它提供了一种从json文档中获取值的快速简单的方法, 它具有单行检索、点符号路径、迭代和解析json行等功能。
开源代码地址: https://github.com/tidwall/gjson Star 10.4k
文档地址:https://pkg.go.dev/github.com/tidwall/gjson
安装 go get -u github.com/tidwall/gjson
要解析的json串如下:
{
"name": {"first": "Tom", "last": "Anderson"},
"age":37,
"children": ["Sara","Alex","Jack"],
"fav.movie": "Deer Hunter",
"friends": [
{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
{"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
{"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
]
}
定义一个json串
const json = `{
"name": {"first": "Tom", "last": "Anderson"},
"age":37,
"children": ["Sara","Alex","Jack"],
"fav.movie": "Deer Hunter",
"friends": [
{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
{"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
{"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
]
}`
校验是否是合法的json格式,代码如下:
if !gjson.Valid(json) {
fmt.Println(errors.New("invalid json"))
}
使用name.last解析name中last的值
value := gjson.Get(json, "name.last")
if !value.Exists() {
println("no last name")
} else {
println(value.String())
}
运行结果如下:
Anderson
其他解析语法规则如下:
"name.last" >> "Anderson"
"age" >> 37
"children" >> ["Sara","Alex","Jack"]
"children.#" >> 3
"children.1" >> "Alex"
"child*.2" >> "Jack"
"c?ildren.0" >> "Sara"
"fav\.movie" >> "Deer Hunter"
"friends.#.first" >> ["Dale","Roger","Jane"]
"friends.1.last" >> "Craig"
friends.#(last=="Murphy").first >> "Dale"
friends.#(last=="Murphy")#.first >> ["Dale","Jane"]
friends.#(age>45)#.last >> ["Craig","Murphy"]
friends.#(first%"D*").last >> "Murphy"
friends.#(first!%"D*").last >> "Craig"
friends.#(nets.#(=="fb"))#.first >> ["Dale","Roger"]
json解析结果转为切片[]Result
result := gjson.Get(json, "friends.#.first")
for _, name := range result.Array() {
println(name.String())
}
运行结果如下:
Dale
Roger
Jane
遍历切片
result1 := gjson.Get(json, "friends.#.first")
result1.ForEach(func(key, value gjson.Result) bool {
fmt.Println(key,value.String())
return true // keep iterating
})
Parse(json)函数可以进行简单的解析,result.Get(path) 可以搜索结果。
例如下面的解析方式都将返回相同的结果:
gjson.Parse(json).Get("name").Get("last")
gjson.Get(json, "name").Get("last")
gjson.Get(json, "name.last")
通过下面方式可以将json解析为map
m, ok := gjson.Parse(json).Value().(map[string]any)
if !ok {
// not a map
}
其中map[string]any,any类型为interface{}类型的别名,type any = interface{}
在go1.18中builtin.go中定义
gjson.GetMany函数可用于同时获取多个值
results := gjson.GetMany(json, "name.first", "name.last", "age")
fmt.Println(results)
运行结果如下:
[Tom Anderson 37]
上面完整代码如下:
package main
import (
"errors"
"fmt"
"github.com/tidwall/gjson"
)
const json = `{
"name": {"first": "Tom", "last": "Anderson"},
"age":37,
"children": ["Sara","Alex","Jack"],
"fav.movie": "Deer Hunter",
"friends": [
{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
{"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
{"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
]
}`
func main() {
if !gjson.Valid(json) {
fmt.Println(errors.New("invalid json"))
}
value := gjson.Get(json, "name.last")
if !value.Exists() {
println("no last name")
} else {
println(value.String())
}
value1 := gjson.Get(json, "children")
fmt.Println(value1)
results := gjson.GetMany(json, "name.first", "name.last", "age")
fmt.Println(results)
result := gjson.Get(json, "friends.#.first")
for _, name := range result.Array() {
println(name.String())
}
result1 := gjson.Get(json, "friends.#.first")
result1.ForEach(func(key, value gjson.Result) bool {
fmt.Println(key,value.String())
return true // keep iterating
})
m, ok := gjson.Parse(json).Value().(map[string]any)
if !ok {
fmt.Println("not a map")
}else {
fmt.Println(m)
}
}
更多使用方式访问: