我有一个很大的 json (30mb),其中包含不同对象中的“标题”字段,json 的结构未知。
只知道 json 包含键“title”,这个键的字符串值必须转换成另一个。
{
"data1" : {
"title" : "alpha",
"color" : "green"
},
"data2" : {
"someInnerData1" : {
"title" : "beta"
"color" : "red"
},
"someInnerData2" : {
"someArray" : [
{
"title" : "gamme",
"color" : "orange"
},
{
"title" : "delta",
"color" : "purple"
}
],
"title" : "epsilon"
}
}
}
替换示例 “α”->“α” “测试版”->“B” 等..
在不解码为结构的情况下,在 Golang 中实现该目标的最佳方法是什么?
P.S. Json是从网络接收的。
最佳答案
您可以使用流式 JSON 解码器,例如 megajson :
// Transform 'title' strings into Title case
func TitleizeJSON(r io.Reader, w io.Writer) error {
buf := new(bytes.Buffer)
r = io.TeeReader(r, buf)
s := scanner.NewScanner(r)
var prevTok int
var prevPos int
wasTitle := false
titleField := []byte("title")
for {
// read the next json token
tok, data, err := s.Scan()
if err == io.EOF {
return nil
} else if err != nil {
return err
}
// calculate the position in the buffer
pos := s.Pos()
off := pos - prevPos
switch tok {
// if this is a string
case scanner.TSTRING:
// if the previous string before a : was 'title', then
// titlelize it
if prevTok == scanner.TCOLON && wasTitle {
// grab the first part of the buffer and skip
// the first ", the titleize the rest
data = buf.Bytes()[:off][1:]
copy(data, bytes.Title(data))
wasTitle = false
} else {
wasTitle = bytes.Equal(data, titleField)
}
}
// now send the data to the writer
data = buf.Bytes()
_, err = w.Write(data[:off])
if err != nil {
return err
}
// reset the buffer (so it doesn't grow forever)
nbuf := make([]byte, len(data)-off)
copy(nbuf, data[off:])
buf.Reset()
buf.Write(nbuf)
// for the next go-around
prevTok = tok
prevPos = pos
}
}
这应该可以即时进行标题化。我能想到的一种情况是,如果你有一个非常非常大的字符串。
关于json - 哪个是处理大 json 和替换特定值的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32328030/