如何在Golang中使用regexp重命名json字符串中的根字段而不影响同名的内部字段? [关闭]

I have a json raw string

{"id":"xxx","person":{"id":"yyy","name":"abc"},"box":{"id":"zzz"}}

I want to rename the field "id" in root to "uuid" without affecting the inner "id" fields.

How can I do this?

I think it is better for you to write some programmatical modificator for the json object. For example, you could try to use https://github.com/qntfy/kazaam or any other json transformation library.

You could also write some data structure with custom json marshaller which takes both "id" on unmarshalling step and produces "uuid" on marshalling step.

regex is the wrong tool for this task. You need to do actual (minimal) JSON parsing. The easiest way to do this is probably with a simple map[string]json.RawMessage, so that only the keys are fully parsed. Example:

var payload map[string]json.RawMessage
if err := json.Unmarshal(input, &payload); err != nil {
    panic(err)
}
payload["uuid"] = payload["id"] // Copy from 'id' to 'uuid'
delete(payload, "id") // Delete the old 'id' key/value
output, err := json.Marshal(payload)
if err != nil {
    panic(err)
}
// output now has your desired content

One thing of which you can take advantage over regex in golang is that when you don't have defined structure for your JSON to be parsed then you can parse that in an map of string and empty interface that is map[string]interface{} Now let's start with initially unmarshing your raw string into such map. Now you can delete the root element of the JSON which you want to change and replace it with another value and again marshal it to get the new string

package main

import (
    "fmt"
    "encoding/json"
)

func main() {
    str := `{"id":"xxx","person":{"id":"yyy","name":"abc"},"box":{"id":"zzz"}}`
    mp := make(map[string]interface{})
    if err := json.Unmarshal([]byte(str), &mp); err != nil {
    fmt.Println("some error occured")
    } else {
        value := mp["id"].(string)
        delete(mp, "id")
        mp["uuid"] = value
    }
    finalAns , _ := json.Marshal(mp)
    fmt.Println(string(finalAns))
}

Output : {"box":{"id":"zzz"},"person":{"id":"yyy","name":"abc"},"uuid":"xxx"}