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)
}
}
更多使用方式訪問: