You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go语言解码JSON前移除Unicode控制字符

实现带控制字符清理的JSON反序列化函数

要实现和json.Unmarshal功能一致但先移除非空格Unicode控制字符的函数,需要同时处理未编码的原生控制字符和JSON编码的\uXXXX形式控制字符,还要区分被转义的\\uXXXX(这类属于普通字符串,不能处理)。

实现思路

  1. 用正则匹配未被转义的\uXXXX序列,判断对应的Unicode字符是否为非空格控制字符,是则移除;
  2. 再处理原生的未编码控制字符,移除其中的非空格控制字符;
  3. 最后调用标准库的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 03:01:07