Go 解码编组的JSON unicode

Go 解码编组的JSON unicode,go,unicode,utf-8,Go,Unicode,Utf 8,我认为解释我的问题的最快方法是: 但这导致了一场灾难 main.go:21:无法在utf8.DecodeRune的参数中使用res type byte作为类型[]字节 在封送对象上调用DecodeRune将返回 { 编辑:我使用的是Go 1.6.2,无论出于何种原因,它显然没有SetEscapeHTML。这是预期的行为。从: 字符串值编码为强制为有效UTF-8的JSON字符串,替换为 使用Unicode替换符文的字节无效。尖括号 转义到\u003c和\u003e以保留某些浏览器 将JSON输出误

我认为解释我的问题的最快方法是:

但这导致了一场灾难

main.go:21:无法在utf8.DecodeRune的参数中使用res type byte作为类型[]字节

在封送对象上调用DecodeRune将返回

{


编辑:我使用的是Go 1.6.2,无论出于何种原因,它显然没有SetEscapeHTML。

这是预期的行为。从:

字符串值编码为强制为有效UTF-8的JSON字符串,替换为 使用Unicode替换符文的字节无效。尖括号 转义到\u003c和\u003e以保留某些浏览器 将JSON输出误解为HTML.Ampersand&也是 出于相同的原因转义到\u0026。可以禁用此转义 使用调用了SetEscapeHTMLfalse的编码器

通过使用编码器并在其上调用SetEscapeHTMLfalse,可以获得所需的结果:


工作示例:

这是预期行为。来自:

字符串值编码为强制为有效UTF-8的JSON字符串,替换为 使用Unicode替换符文的字节无效。尖括号 转义到\u003c和\u003e以保留某些浏览器 将JSON输出误解为HTML.Ampersand&也是 出于相同的原因转义到\u0026。可以禁用此转义 使用调用了SetEscapeHTMLfalse的编码器

通过使用编码器并在其上调用SetEscapeHTMLfalse,可以获得所需的结果:


工作示例:

顺便说一句,这里是编译器错误的原因

Marshal返回字节片[]字节,而不是字符串

当您使用范围在字节片上迭代时,您不是在其符文上迭代,而是一次在单个字节上迭代。您不能在字节值上使用DecodeRune-它需要符文,这是表示Unicode代码点的32位整数值。如果您在字符串上使用范围进行迭代,将得到此结果

现在,从你想要达到的目标来看,你根本不想要破译符文

另一个答案充分描述了如何告诉JSON编码不要转义字符

enc := json.NewEncoder(os.Stdout)
enc.SetEscapeHTML(false)

顺便说一下,这里是编译器错误的原因

Marshal返回字节片[]字节,而不是字符串

当您使用范围在字节片上迭代时,您不是在其符文上迭代,而是一次在单个字节上迭代。您不能在字节值上使用DecodeRune-它需要符文,这是表示Unicode代码点的32位整数值。如果您在字符串上使用范围进行迭代,将得到此结果

现在,从你想要达到的目标来看,你根本不想要破译符文

另一个答案充分描述了如何告诉JSON编码不要转义字符

enc := json.NewEncoder(os.Stdout)
enc.SetEscapeHTML(false)

实现这一点的另一个解决方案是简单地将这些转义字符替换为未转义的UTF-8字符

可以使用和进行转换

func _UnescapeUnicodeCharactersInJSON(_jsonRaw json.RawMessage) (json.RawMessage, error) {
    str, err := strconv.Unquote(strings.Replace(strconv.Quote(string(_jsonRaw)), `\\u`, `\u`, -1))
    if err != nil {
        return nil, err
    }
    return []byte(str), nil
}

func main() {
    // Both are valid JSON.
    var jsonRawEscaped json.RawMessage   // json raw with escaped unicode chars
    var jsonRawUnescaped json.RawMessage // json raw with unescaped unicode chars

    // '\u263a' == '☺'
    jsonRawEscaped = []byte(`{"HelloWorld": "\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a"}`) // "\\u263a"
    jsonRawUnescaped, _ = _UnescapeUnicodeCharactersInJSON(jsonRawEscaped)                        // "☺"

    fmt.Println(string(jsonRawEscaped))   // {"HelloWorld": "\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a"}
    fmt.Println(string(jsonRawUnescaped)) // {"HelloWorld": "안녕, 세상(世上). ☺"}
}

我希望这会有所帮助。

实现这一点的另一个解决方案是简单地将转义字符替换为未转义的UTF-8字符。我过去这样做是为了使非英语字母在JSON中具有可读性

可以使用和进行转换

func _UnescapeUnicodeCharactersInJSON(_jsonRaw json.RawMessage) (json.RawMessage, error) {
    str, err := strconv.Unquote(strings.Replace(strconv.Quote(string(_jsonRaw)), `\\u`, `\u`, -1))
    if err != nil {
        return nil, err
    }
    return []byte(str), nil
}

func main() {
    // Both are valid JSON.
    var jsonRawEscaped json.RawMessage   // json raw with escaped unicode chars
    var jsonRawUnescaped json.RawMessage // json raw with unescaped unicode chars

    // '\u263a' == '☺'
    jsonRawEscaped = []byte(`{"HelloWorld": "\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a"}`) // "\\u263a"
    jsonRawUnescaped, _ = _UnescapeUnicodeCharactersInJSON(jsonRawEscaped)                        // "☺"

    fmt.Println(string(jsonRawEscaped))   // {"HelloWorld": "\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a"}
    fmt.Println(string(jsonRawUnescaped)) // {"HelloWorld": "안녕, 세상(世上). ☺"}
}

我希望这有帮助。

我看到它在操场上工作,但当我将它复制到自己的环境中时,我得到了一个编译错误:enc.SetEscapeHTML undefined type*json.Encoder没有字段或方法SetEscapeHTML。如果有任何变化,我将使用Go 1.6.2。可能是该方法在1.6.2中不可用。请尝试检查您版本的文档此处描述:嗯,是的。文档中没有提到SetEscapeHTML,也没有提供任何其他替代方案。SetEscapeHTML是在Go 1.7中添加的。由于json库只对三个字符执行此操作,您可以尝试这样的操作:我看到它在操场上工作,但当我将其复制到自己的环境中时,会出现编译错误:enc.SetEscapeHTML undefined type*json.Encoder没有字段或方法SetEscapeHTML。如果有任何变化,我正在使用Go 1.6.2。可能是该方法在1.6.2中不可用。请尝试检查您版本的文档,如下所述:嗯,是的。这些文档没有提及SetEscapeHTML,也没有提供任何其他替代方法。SetEscapeHTML是在Go 1.7.Sinc中添加的e json库仅对三个字符执行此操作,您可以尝试以下操作:
func _UnescapeUnicodeCharactersInJSON(_jsonRaw json.RawMessage) (json.RawMessage, error) {
    str, err := strconv.Unquote(strings.Replace(strconv.Quote(string(_jsonRaw)), `\\u`, `\u`, -1))
    if err != nil {
        return nil, err
    }
    return []byte(str), nil
}

func main() {
    // Both are valid JSON.
    var jsonRawEscaped json.RawMessage   // json raw with escaped unicode chars
    var jsonRawUnescaped json.RawMessage // json raw with unescaped unicode chars

    // '\u263a' == '☺'
    jsonRawEscaped = []byte(`{"HelloWorld": "\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a"}`) // "\\u263a"
    jsonRawUnescaped, _ = _UnescapeUnicodeCharactersInJSON(jsonRawEscaped)                        // "☺"

    fmt.Println(string(jsonRawEscaped))   // {"HelloWorld": "\uC548\uB155, \uC138\uC0C1(\u4E16\u4E0A). \u263a"}
    fmt.Println(string(jsonRawUnescaped)) // {"HelloWorld": "안녕, 세상(世上). ☺"}
}