Golang解析带转义字符的JSON 如何提取getField内的ThisIsWhatIwant字段
Go提取嵌套JSON字符串指定字段的实现方法
核心逻辑:你遇到的是JSON嵌套序列化场景:getField字段的内容本身是被序列化为字符串的JSON对象,所以需要做两次反序列化:第一次解析外层JSON拿到getField的字符串值,第二次解析这个字符串得到内层JSON的字段。
注意:你给出的示例里内层JSON存在语法错误(部分Value没有加双引号,比如
"Key":Value),请先修正为合法JSON格式再做解析,以下演示基于修正后的合法JSON。
实现方式1:定义结构体(推荐)
这种方式性能好、类型安全,不需要的字段可以不用定义,反序列化时会自动忽略:
package main import ( "encoding/json" "fmt" ) // 定义内层getField对应的结构,只保留需要的字段即可 type InnerField struct { ThisIsWhatIwant string `json:"**ThisIsWhatIwant**"` } // 定义外层数组的元素结构 type TestItem struct { GetField string `json:"getField"` // 其他不需要的字段可以不用定义,自动忽略 } // 定义最外层JSON结构 type OuterJSON struct { Test []TestItem `json:"test"` } func main() { // 替换为实际的原始JSON数据源 rawJSON := []byte(` { "test": [ { "test": "test", "source": "test", "description": [ "test" ], "getField": "{\"Key\":\"Value\",\"Key2\":\"Value\",\"**ThisIsWhatIwant**\":\"test\",\"Key3\":\"Value\",\"Key4\":0,\"Key5\":\"value\",\"Key6\":\"value\"}" } ] } `) // 第一次反序列化:解析外层JSON var outer OuterJSON if err := json.Unmarshal(rawJSON, &outer); err != nil { panic(fmt.Sprintf("外层JSON解析失败:%v", err)) } // 遍历test数组,确定只有一个元素可直接取outer.Test[0] for _, item := range outer.Test { // 第二次反序列化:解析getField里的内层JSON字符串 var inner InnerField if err := json.Unmarshal([]byte(item.GetField), &inner); err != nil { panic(fmt.Sprintf("内层JSON解析失败:%v", err)) } // 输出目标字段 fmt.Println("提取到的目标字段值:", inner.ThisIsWhatIwant) } }
实现方式2:用map快速解析(适合临时调试)
如果不想提前定义结构体,可直接反序列化到map[string]interface{}类型,无需提前知道完整JSON结构:
package main import ( "encoding/json" "fmt" ) func main() { // 替换为实际的原始JSON数据源 rawJSON := []byte(`/* 同上原始JSON内容 */`) // 第一次解析外层到map var outerMap map[string]interface{} if err := json.Unmarshal(rawJSON, &outerMap); err != nil { panic(err) } // 层级取值,生产环境建议加类型断言判断避免panic testArr := outerMap["test"].([]interface{}) testItem := testArr[0].(map[string]interface{}) getFieldStr := testItem["getField"].(string) // 第二次解析内层到map var innerMap map[string]interface{} if err := json.Unmarshal([]byte(getFieldStr), &innerMap); err != nil { panic(err) } // 直接取目标字段 targetVal := innerMap["**ThisIsWhatIwant**"].(string) fmt.Println("提取到的目标字段值:", targetVal) }
内容的提问来源于stack exchange,提问作者Gerard Geded
相关产品推荐
相关产品推荐

