使用不可打印的ASCII字符解组JSON

时间:2018-11-04 05:07:27

标签: json go

使用Go,我如何解组包含不可打印ASCII字符的JSON字符串?

例如

testJsonString := "{\"test_one\" : \"123\x10456\x0B789\v123\a456\"}"
var dat map[string]interface{}
err := json.Unmarshal([]byte(testJsonString), &dat)
if err != nil {
    panic(err)
}

收益:

panic: invalid character '\x10' in string literal

goroutine 1 [running]:
main.main()
    /tmp/sandbox903140350/main.go:14 +0x180

https://play.golang.org/p/mFGWzndDK8V

不幸的是,我无法控制源数据,因此我需要一种忽略或去除不可打印字符的方法。

类似地,我遇到的另一个数据问题也剥离了一些C转义序列-如\ 0和\ a。如果我用下面的这个字符串替换上面列出的字符串,该程序也会失败。本质上,它也不能在任何C转义序列https://en.wikipedia.org/wiki/Escape_sequences_in_C

上失败
testJsonString := "{\"test_one\" : \"123456789\\a123456\"}"

将出现错误

panic: invalid character 'a' in string escape code

goroutine 1 [running]:
main.main()
    /tmp/sandbox322770276/main.go:12 +0x100

这似乎也无法解组,但是无法通过符文数字检查或unicode进行转义(因为Go似乎将其视为反斜杠,后跟字符“ a”,两者都法律)

有处理这些极端情况的好方法吗?

1 个答案:

答案 0 :(得分:0)

根据JSON规范https://jsonapi.org/format/,不可打印字符应转义URI(或转换为有效的Unicode转义)

因此,这是一个转换器,可将不可打印的字符转换为uri转义的形式。然后可以将它们送入元帅

如果这不是您所需要的行为,请修改转换器以删除字符(使用continue)或替换为问号符文或其他任何符号

顺便说一句,\\a的第二个问题对我来说不是“按预期打印”。请举一个更好的例子,实际显示您遇到的问题

    package main

    import (
        "bytes"
        "encoding/json"
        "fmt"
        "unicode"
        "net/url"
    )

func safety(d string) []byte {
    var buffer bytes.Buffer
    for _, c := range d {
        s := string(c)
        if c == 92 { // 92 is a backslash
          continue
        }
        if unicode.IsPrint(c) {        
            buffer.WriteString(s)
        } else {
            buffer.WriteString(url.QueryEscape(s))
        }
        fmt.Println(buffer.String())
    }
    return buffer.Bytes()
}

func main() {
    testJsonString := "{\"test_one\" : \"123\x10456\x0B789\v123\a456\"}"
    var dat map[string]interface{}
    err := json.Unmarshal(safety(testJsonString), &dat)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%v", dat)
}