Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 从字符串中删除无效的UTF-8字符_Json_Unicode_Go - Fatal编程技术网

Json 从字符串中删除无效的UTF-8字符

Json 从字符串中删除无效的UTF-8字符,json,unicode,go,Json,Unicode,Go,我在json.Marshal的字符串列表中得到了这一点: json: invalid UTF-8 in string: "...ole\xc5\" 原因很明显,但如何在Go中删除/替换此类字符串?我一直在读关于unicode和unicode/utf8软件包的docst,似乎没有明显的/快速的方法 例如,在Python中,有一些方法可以删除无效字符,替换为指定字符或严格设置,从而引发无效字符异常。我怎样才能在围棋中做同样的事情 更新:我指的是得到异常(恐慌?)的原因——json.Marshal期

我在json.Marshal的字符串列表中得到了这一点:

json: invalid UTF-8 in string: "...ole\xc5\"
原因很明显,但如何在Go中删除/替换此类字符串?我一直在读关于
unicode
unicode/utf8
软件包的docst,似乎没有明显的/快速的方法

例如,在Python中,有一些方法可以删除无效字符,替换为指定字符或严格设置,从而引发无效字符异常。我怎样才能在围棋中做同样的事情

更新:我指的是得到异常(恐慌?)的原因——json.Marshal期望的有效UTF-8字符串中的非法字符

(非法字节序列如何进入该字符串并不重要,通常的方式是错误、文件损坏、其他不符合unicode的程序等)

例如

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    s := "a\xc5z"
    fmt.Printf("%q\n", s)
    if !utf8.ValidString(s) {
        v := make([]rune, 0, len(s))
        for i, r := range s {
            if r == utf8.RuneError {
                _, size := utf8.DecodeRuneInString(s[i:])
                if size == 1 {
                    continue
                }
            }
            v = append(v, r)
        }
        s = string(v)
    }
    fmt.Printf("%q\n", s)
}
输出:

"a\xc5z"
"az"

问:是否有任何字节序列不是由UTF生成的?怎么 我应该翻译吗

答:没有一个UTF可以生成每个任意字节序列。对于 例如,在UTF-8中,必须遵循110xxxxx2格式的每个字节 具有格式为10xxxxxx2的字节。这样的序列是非法的,决不能生成。面对 这种非法字节序列在转换或解释UTF-8时发生 一致进程必须将第一个字节110xxxxx2视为非法 终止错误:例如,发送错误信号、过滤 字节out,或用标记(如FFFD)表示字节 (替换字符)。在后两种情况下,它将继续下去 在第二个字节0xxxxxxx2处处理

一致进程不得解释非法或格式错误的字节 但是,它可能会采取错误恢复操作。 一致性进程不能使用不规则字节序列进行编码 带外信息


在Go 1.13+中,您可以这样做:

strings.ToValidUTF8("a\xc5z", "")
fixUtf := func(r rune) rune {
    if r == utf8.RuneError {
        return -1
    }
    return r
}

fmt.Println(strings.Map(fixUtf, "a\xc5z"))
fmt.Println(strings.Map(fixUtf, "posic�o"))
az
posico

在Go 1.11+中,使用和也很容易做到这一点:

strings.ToValidUTF8("a\xc5z", "")
fixUtf := func(r rune) rune {
    if r == utf8.RuneError {
        return -1
    }
    return r
}

fmt.Println(strings.Map(fixUtf, "a\xc5z"))
fmt.Println(strings.Map(fixUtf, "posic�o"))
az
posico
输出:

strings.ToValidUTF8("a\xc5z", "")
fixUtf := func(r rune) rune {
    if r == utf8.RuneError {
        return -1
    }
    return r
}

fmt.Println(strings.Map(fixUtf, "a\xc5z"))
fmt.Println(strings.Map(fixUtf, "posic�o"))
az
posico

操场:

原因如何显而易见?我想您可能有一个拉丁1(或ISO8859的其他变体)字符串,在这种情况下,您不希望函数吞下这些字符,而是在继续之前将它们转换为UTF-8…在Go 1.2中,json解析器将接受格式错误的UTF-8。它将用替换标志符替换格式错误的字节。虽然很可能完全不相关,但您的示例可能会删除完全正确的编码Unicode替换字符(
“\xef\xbf\xbd”
)如果字符串还包含断开的UTF8序列。@ANisus:假设人们已经阅读了Unicode标准。我的评论只是一些琐事。我的函数还将删除替换字符和非法序列(毕竟是我的+1;)。我刚才说,json.Marshal将接受的“\xef\xbf\xbd”的合法字节序列也将被剥离。我不确定Unicode标准怎么会不同意。@ANisus:如果你愿意,你可以保留任何替换字符。请看我修改后的答案。@Roylee:相同的东西,不同的名称:和.FYI,
strings.ToValidUTF8
没有进入Go 1.12,但看起来它是为Go 1.13计划的: