使用iancoleman/orderedmap实现JSON字符串往返编解码时保留特殊字符编码的问题
iancoleman/orderedmap实现JSON字符串往返编解码时保留特殊字符编码的问题
看起来你遇到的核心问题是:在Go中使用iancoleman/orderedmap处理JSON时,无法保留输入里的HTML转义特殊字符(比如&、<br>),导致编解码后的输出和原始输入不一致。下面我们一步步拆解原因并给出解决方案。
问题根源分析
你的输入字符串是经过HTML转义的JSON,但直接用json.Unmarshal解析时会出现两个关键问题:
- JSON解析器本身不处理HTML转义:输入里的
&是HTML实体,代表原始的&字符,但你直接解析这个HTML转义后的JSON,会导致解析后的字符串中实际存储的是&、<这类原始字符,而非你期望保留的&、<br>。 - Go的JSON编码器默认会转义特殊字符:无论你设置
SetEscapeHTML(true/false),编码器都会对&、<进行转义——true时转成HTML实体(比如&),false时转成Unicode转义序列(比如\u0026),都无法还原你输入里的原始HTML转义格式。
解决方案:加入HTML转义/反转义的中间处理
要实现输入输出完全一致,你需要在编解码流程中嵌入HTML转义的处理逻辑,确保解析的是标准JSON,编码后再还原为HTML转义格式:
完整可运行代码
package main import ( "bytes" "encoding/json" "fmt" "html" orderedmap "github.com/iancoleman/orderedmap" ) func main() { var testObj = orderedmap.New() // 你的原始输入:HTML转义后的JSON字符串 inputStr := "{\"\\\" & <br> 😃\": 1}" fmt.Println("Input:", inputStr) // 1. 先对输入做HTML反转义,得到标准JSON(包含&、<等原始字符) rawJSON := html.UnescapeString(inputStr) // 2. 解析标准JSON到orderedmap err := json.Unmarshal([]byte(rawJSON), &testObj) if err != nil { panic(err) } // (可选)在这里修改JSON内容,比如把值从1改成2 testObj.Set("\" & <br> 😃", 2) // 3. 将修改后的orderedmap编码为标准JSON字符串 var buf bytes.Buffer encoder := json.NewEncoder(&buf) encoder.SetEscapeHTML(false) // 避免编码时生成HTML实体,保持原始字符 encoder.Encode(testObj) encodedJSON := string(buf.Bytes()) // 去掉Encode自动添加的换行符 encodedJSON = encodedJSON[:len(encodedJSON)-1] // 4. 对编码后的标准JSON做HTML转义,还原为输入的格式 outputStr := html.EscapeString(encodedJSON) fmt.Println("Output (matches input):", outputStr) }
代码关键步骤说明
- HTML反转义:用
html.UnescapeString把输入里的&、<br>转成&、<br>,得到符合JSON规范的原始字符串,确保解析逻辑正确。 - JSON解析与修改:正常解析到
orderedmap后,你可以自由修改JSON的内容,不会影响特殊字符的后续还原。 - JSON编码:设置
SetEscapeHTML(false)避免编码器生成HTML实体,保持字符串里的&、<等原始字符。 - HTML转义还原:最后用
html.EscapeString把编码后的JSON里的&、<转回到&、<,完美匹配你输入的格式。
运行输出
Input: {"\" & <br> 😃": 1} Output (matches input): {"\" & <br> 😃":2}
额外提示
如果你不需要修改JSON内容,只是想原样复制输入字符串,直接复用原始字符串即可,不需要走编解码流程。但如果需要修改JSON结构的其他部分,上述流程可以确保你精准保留原始的HTML转义格式。
内容来源于stack exchange
相关产品推荐
相关产品推荐

