我正在尝试将 ISO 8859-1 编码字符串转换为 UTF-8。
以下函数适用于我的包含德语变音符号的测试数据,但我不太确定 rune(b) 强制转换采用的源编码。是否假设某种默认编码,例如ISO8859-1 或者有什么办法告诉它使用什么编码?
func toUtf8(iso8859_1_buf []byte) string {
var buf = bytes.NewBuffer(make([]byte, len(iso8859_1_buf)*4))
for _, b := range(iso8859_1_buf) {
r := rune(b)
buf.WriteRune(r)
}
return string(buf.Bytes())
}
rune 是 int32 的别名,在编码时,假设 rune 具有 Unicode 字符值(代码点)。所以
b
中的值 rune(b)
应该是一个 unicode 值。对于 0x00 - 0xFF,该值与 Latin-1 相同,因此您不必担心。
然后你需要将符文编码为UTF8。但这种编码只是通过将
[]rune
转换为 string
来完成。
这是不使用 bytes 包的函数示例:
func toUtf8(iso8859_1_buf []byte) string {
buf := make([]rune, len(iso8859_1_buf))
for i, b := range iso8859_1_buf {
buf[i] = rune(b)
}
return string(buf)
}
效果
r := rune(expression)
是:
r
的变量 rune
(int32 的别名)。r
。不涉及(重新)编码,并且只能通过在代码中显式编写/处理一些重新编码来说明应该选择使用哪一种编码。幸运的是,在这种情况下不需要(重新)编码,Unicode 以与 ASCII 类似的方式合并了 ISO 8859-1 的这些代码。 (如果我检查正确这里)
要在任何 ISO-8859 变体(和其他流行的遗留代码页)和 UTF-8 之间进行转换,请使用 golang.org/x/text/encoding/charmap。
解码这个 latin1 编码:
// rivière, è latin1-encoded as 233 (0xe9)
bLatin1 := []byte{114, 105, 118, 105, 233, 114, 101}
Charmap 类型有一个 NewDecoder 方法,该方法返回 *encoding.Decoder:
dec8859_1 := charmap.ISO8859_1.NewDecoder()
该解码器可以直接解码字节:
bUTF8, _ := dec8859_1.Bytes(bLatin1)
fmt.Printf("% #x\n", bLatin1) // 0x72 0x69 0x76 0x69 0xe9 0x72 0x65
fmt.Printf("% #x\n", bUTF8) // 0x72 0x69 0x76 0x69 0xc3 0xa9 0x72 0x65
如果您有旧编码的文件:
f, _ := os.Create("foo.txt")
f.Write(bLatin1)
f.Write([]byte("\n"))
f.Write([]byte("Seine"))
使用解码器来包装文件的阅读器:
f, _ = os.Open("foo.txt")
rLatin1 := dec8859_1.Reader(f)
并传递新的解码器-Reader:
scanner := bufio.NewScanner(rLatin1)
for i := 1; scanner.Scan(); i++ {
fmt.Printf("line %d: %s\n", i, scanner.Text())
}
// line 1: riviére
// line 2: Seine