golang 将 iso8859-1 转换为 utf8

问题描述 投票:0回答:3

我正在尝试将 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())
}
character-encoding go
3个回答
19
投票

runeint32 的别名,在编码时,假设 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)
}

2
投票

效果

r := rune(expression)

是:

  • 声明类型为
    r
    的变量
    rune
    (int32 的别名)。
  • 用表达式的值初始化变量
    r

不涉及(重新)编码,并且只能通过在代码中显式编写/处理一些重新编码来说明应该选择使用哪一种编码。幸运的是,在这种情况下不需要(重新)编码,Unicode 以与 ASCII 类似的方式合并了 ISO 8859-1 的这些代码。 (如果我检查正确这里


0
投票

要在任何 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
© www.soinside.com 2019 - 2024. All rights reserved.