我认为解释我问题的最快方法是使用example:
package main
import (
"fmt"
"encoding/json"
)
type JSON struct {
Body string
}
func main() {
body := "<html><body>Hello World</body></html>"
obj := JSON{body}
result, _ := json.Marshal(obj)
fmt.Println(string(result))
}
输出:
{&#34; Body&#34;:&#34; \ u003chtml \ u003e \ u003cbody \ u003eHello World \ u003c / body \ u003e \ u003c / html \ u003e&#34;}
我希望结果是一个utf8编码的字符串,其读取内容相同。我怎样才能实现这一目标?我试图在循环中使用utf8.DecodeRune,
:
str := ""
for _, res := range result {
decoded, _ := utf8.DecodeRune(res)
str += string(decoded)
}
但这会导致compilation error
main.go:21:不能使用res(类型字节)作为utf8.DecodeRune的参数中的类型[]字节
在编组对象上调用DecodeRune
会返回first character,因为您需要
{
编辑:我使用的是Go 1.6.2,由于某种原因,显然没有SetEscapeHTML
。
答案 0 :(得分:5)
这是预期的行为。来自docs:
字符串值编码为强制转换为有效UTF-8的JSON字符串,替换 Unicode替换符号的无效字节。尖括号 &#34;&LT;&#34;和&#34;&gt;&#34;被转移到&#34; \ u003c&#34;和&#34; \ u003e&#34;保留一些浏览器 从错误解释JSON输出为HTML。 &符&#34;&amp;&#34;也是 逃到了#34; \#34; \#34;出于同样的原因。可以禁用此转义 使用调用了SetEscapeHTML(false)的编码器。
您可以使用Encoder
并在其上调用SetEscapeHTML(false)
来获得所需的结果:
func main() {
body := "<html><body>Hello World</body></html>"
obj := JSON{body}
enc := json.NewEncoder(os.Stdout)
enc.SetEscapeHTML(false)
enc.Encode(obj)
}
答案 1 :(得分:2)
另一种实现此目的的方法是将那些转义的字符替换为未转义的UTF-8字符。 (我曾经这样做是为了使非英语字母在JSON中易于人读。)
您可以使用strconv.Quote()
和strconv.Unquote()
进行转换。
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": "안녕, 세상(世上). ☺"}
}
https://play.golang.org/p/pUsrzrrcDG-
我希望这会有所帮助。
答案 2 :(得分:0)
顺便说一句,这就是编译错误的原因。
json.Marshal返回一个字节切片([]byte
),而不是字符串。
当您使用range
迭代字节切片时,您不会迭代其符文,而是一次超过单个字节。您不能在字节值上使用DecodeRune()
- 它需要一个符文,这是一个32位整数值,表示Unicode代码点。如果您在字符串上使用range
进行迭代,这就是您所获得的。
现在,根据您想要实现的目标,看起来您根本不想要DecodeRune。
另一个答案充分描述了如何告诉JSON编码不要转义<
和>
字符,即
enc := json.NewEncoder(os.Stdout)
enc.SetEscapeHTML(false)