【问题标题】:Golang Decoding/Unmarshaling invalid unicode in JSONGolang解码/解组JSON中的无效unicode
【发布时间】:2014-06-20 03:58:19
【问题描述】:

我在 go 中获取格式不统一的 JSON 文件。 例如,我可以有以下内容:

{"email": "\"blah.blah@blah.com\""}
{"email": "robert@gmail.com"}
{"name": "m\303\203ead"}

我们可以看到转义字符会有问题。 使用json.Decode

与:

{"name": "m\303\203ead"}

我收到错误:invalid character '3' in string escape code

我尝试了几种方法来规范化我的数据,例如传递一个字符串数组(它可以工作,但有太多边缘情况),甚至过滤转义字符。

最后,我通过了这篇文章:(http://blog.golang.org/normalization) 他们提出的解决方案似乎很有趣。

我已经尝试了以下

isMn := func(r rune) bool {
    return unicode.Is(unicode.Mn, r)
}

t := transform.Chain(norm.NFC, transform.RemoveFunc(isMn), norm.NFD)

fileReader, err := bucket.GetReader(filename)

transformReader := transform.NewReader(fileReader, t)

decoder := json.NewDecoder(tReader)

for {
    var dataModel Model
    if err := decoder.Decode(&kmData); err == io.EOF {
        break
    } else {
      // DO SOMETHING
    }
}

Model 是:

type Model struct {
    Name  string `json:"name" bson:"name"`
    Email string `json:"email" bson:"email"` 
}

我已经尝试了它的几种变体,但无法让它工作。

所以我的问题是如何轻松处理解码/解组具有不同编码的 JSON 数据?知道我无法控制这些 JSON 文件。

如果您正在阅读本文,无论如何,谢谢。

【问题讨论】:

    标签: json unicode go


    【解决方案1】:

    您可以使用json.RawMessage 代替string,这样json.Decode 就不会尝试解码无效字符。

    游乐场:http://play.golang.org/p/fB-38KGAO0

    type Model struct {
        N  json.RawMessage `json:"name" bson:"name"`
    }
    
    func (m *Model) Name() string {
        return string(m.N)
    }
    func main() {
        s := "{\"name\": \"m\303\203ead\"}"
        r := strings.NewReader(s)
        d := json.NewDecoder(r)
        m := Model{}
    
        fmt.Println(d.Decode(&m))
        fmt.Println(m.Name())
    }
    

    编辑:嗯,你可以使用正则表达式,不确定这对你有多可行http://play.golang.org/p/VYJKTKmiYm

    func cleanUp(s string) string {
        re := regexp.MustCompile(`\b(\\\d\d\d)`)
        return re.ReplaceAllStringFunc(s, func(s string) string {
            return `\u0` + s[1:]
        })
    }
    func main() {
        s := "{\"name\": \"m\303\203ead\"}"
        s = cleanUp(s)
        r := strings.NewReader(s)
        d := json.NewDecoder(r)
        m := Model{}
        fmt.Println(d.Decode(&m))
        fmt.Println(m.Name())
    }
    

    【讨论】:

    • 真的很好。 +1。毫无疑问,我也会使用它。
    • 很棒的解决方案。如果确实解决了这种情况,它仍然无法解决数据编码错误的情况,例如 here 。我很想将每个 `` 替换为 nil,但这很冒险......
    • 我现在什么都做不了,必须在解析之前对 json 文本进行预处理。
    • 是的,它成功了,谢谢!但我最终在解码 JSON 之前将其转换为字符串
    猜你喜欢
    • 1970-01-01
    • 2014-06-12
    • 1970-01-01
    • 2017-09-23
    • 2022-12-29
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多