从字符串中删除无效的UTF-8字符(Go lang)

时间:2013-12-05 13:56:57

标签: json unicode go

我在字符串列表的json.Marshal上得到了这个:

json: invalid UTF-8 in string: "...ole\xc5\"

原因很明显,但是如何在Go中删除/替换这些字符串?我一直在阅读unicodeunicode/utf8软件包上的docst,似乎没有明显/快捷的方法。

在Python中,您可以使用以下方法来删除无效字符,替换为指定字符或严格设置,这会在无效字符上引发异常。我怎样才能在Go中做同等的事情?

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

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

2 个答案:

答案 0 :(得分:18)

例如,

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"
  

Unicode Standard

     

FAQ - UTF-8, UTF-16, UTF-32 & BOM

     

问:是否有任何UTF未生成的字节序列?怎么样   我应该解读一下吗?

     

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

     

符合要求的过程不得解释非法或格式错误的字节   但是,序列作为字符可能需要进行错误恢复操作。   没有一致的过程可能使用不规则的字节序列来编码   带外信息。

答案 1 :(得分:4)

从Go 1.12开始,您还可以执行以下操作:

strings.ToValidUTF8("a\xc5z", nil)

在Go 1.11中,使用Map functionutf8.RuneError这样的操作也非常容易:

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

游乐场: Here