如何在Go语言解码JSON前移除Unicode控制字符
实现带控制字符清理的JSON反序列化函数
要实现和json.Unmarshal功能一致但先移除非空格Unicode控制字符的函数,需要同时处理未编码的原生控制字符和JSON编码的\uXXXX形式控制字符,还要区分被转义的\\uXXXX(这类属于普通字符串,不能处理)。
实现思路
- 用正则匹配未被转义的
\uXXXX序列,判断对应的Unicode字符是否为非空格控制字符,是则移除; - 再处理原生的未编码控制字符,移除其中的非空格控制字符;
- 最后调用标准库的
json.Unmarshal完成反序列化。
完整代码
import ( "encoding/json" "regexp" "strconv" "strings" "unicode" ) // cleanJSON 移除JSON中所有非空格的Unicode控制字符(含编码形式) func cleanJSON(data []byte) []byte { // 处理JSON编码的\uXXXX形式控制字符 unicodeEscapeRegex := regexp.MustCompile(`(?<!\\)\\u([0-9a-fA-F]{4})`) cleaned := unicodeEscapeRegex.ReplaceAllFunc(data, func(match []byte) []byte { // 提取十六进制部分(跳过"\u"前缀) hexStr := string(match[2:]) codePoint, err := strconv.ParseUint(hexStr, 16, 32) if err != nil { // 无效的Unicode转义,保留原内容 return match } r := rune(codePoint) // 判断是否为非空格控制字符,是则移除 if unicode.IsControl(r) && !unicode.IsSpace(r) { return []byte{} } return match }) // 处理原生未编码的控制字符 cleanedStr := strings.Map(func(r rune) rune { if unicode.IsControl(r) && !unicode.IsSpace(r) { return -1 } return r }, string(cleaned)) return []byte(cleanedStr) } // CustomUnmarshal 等效于json.Unmarshal,但会先清理非空格Unicode控制字符 func CustomUnmarshal(data []byte, v any) error { cleanedData := cleanJSON(data) return json.Unmarshal(cleanedData, v) }
效果验证
针对你给出的输入:
{"name":"\b\t\u0009Some\u0000thing\\u0002"}
经过cleanJSON处理后输出:
{"name":"\t\u0009Something\\u0002"}
完全符合预期:
\b(退格符)被移除;\t和\u0009(制表符,属于空格类控制字符)保留;\u0000(空字符)被移除;\\u0002(转义后的斜杠+编码序列)完整保留。
内容的提问来源于stack exchange,提问作者Prutser
相关产品推荐
相关产品推荐

