json - 在解码之前从 json 之类的字符串中去除无效 json 字符的最佳方法

标签 json go unmarshalling utf

为了提供一些背景知识,我正在使用 adb logcat 和 idevicesyslog 从 android 和 ios 设备读取设备日志。我所关注的具体日志是通过 adb logcat/idevicesyslog 将 swift/c#/java/etc 字典转换为字符串。我希望获取这些包含类似字符串的 JSON 的日志,并将它们转换为有效的 JSON。这在大多数情况下都没有问题。

但是,有时这些日志/字符串输出包含(\134、\M、\t 等)等字符,在解码为 JSON 时会导致问题。我将它们解码为 JSON 以将它们发送到其他地方。

例如,原始设备日志可能包含如下内容: {"foo":"bar","foo":"bar\134/\134/bar\134/bar\134/bar"} {"foo":"bar","foo":"bar\M/\134/bar\134/bar\M/bar"}

当尝试解码时,这些会导致错误,例如“ panic :字符串转义代码中的无效字符‘M’”

大多数日志不包含这些字符,因此这不是问题。然而,一些边缘情况包含这些并且会产生问题。

这些类型的字符有合适的名称吗? (c# 转义字符?)是否有可以从字符串中删除它们的 golang 包?目前,如果它们出现在字符串中,我只是删除我遇到的特定的,但我觉得有更好的方法来做到这一点。将我遇到的字符添加到可删除字符列表中并不是一个好的做法。

总而言之,

idevicesyslog 日志给我一个像这样的字符串: {"foo":"bar","foo":"bar\134/\134/bar\134/bar\134/bar"}

这无法解码。

idevicesyslog 日志给我一个像这样的字符串: {"foo":"bar","foo":"bar bar bar bar"}

这可以解码。

当前的解决方案:将我遇到的新问题添加到列表中并在解码之前将其删除

有希望的解决方案:自动检测并删除

最佳答案

使用正则表达式将无效的八进制转义序列替换为空格:

var octalEscapePat = regexp.MustCompile(`\\[0-7]{3}`)

func fix(src string) string {
    return octalEscapePat.ReplaceAllString(src, " ")
}

您还可以解析八进制值并转换为有效的 JSON 转义序列:

func fix(src string) string {
    return octalEscapePat.ReplaceAllStringFunc(src, func(s string) string {
        // Parse octal value
        n, _ := strconv.ParseInt(s[1:], 8, 0)
        // Convert to string and marshal to JSON to handle any escaping
        b, _ := json.Marshal(string(n))
        // return string with surrounding quotes removed
        return string(b[1 : len(b)-1])
    })
}

\M 可以用类似的方式处理。

https://play.golang.org/p/-gtxrvnBSrx

关于json - 在解码之前从 json 之类的字符串中去除无效 json 字符的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54271767/

相关文章:

java - 无法使用 JSON 和 JQuery 显示从 Spring MVC Controller 返回的响应

JavaScript 和 JSON 数组

string - 通过强制转换和使用串联运算符将整数附加到字符串

xml - Go 中使用嵌套 XML-RPC 解码组

php - 用于 PHP 的 JAXB(PAXB?)

java - JAXB:未编码的 XML 中缺少 "xsi-type"属性

javascript - 如何在webworker中连续发送xmlhttprequest?

java - Android NetworkOnMainThreadException 异常

go - 如何在 Go 中获取 $PATH 中可执行文件的完整路径

go - 如何在 cgo 中正确使用 64 位 TDM-GCC?