在 Go 中使用 bufio 扫描器读取 unicode 字符
Read unicode characters with bufio scanner in Go
我正在尝试读取包含如下名称的纯文本文件:"CASTAÑEDA"
代码基本是这样的:
file, err := os.Open("C:/Files/file.txt")
defer file.Close()
if err != nil {
log.Fatal(err)
}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
然后,当读取 "CASTAÑEDA" 时,它会打印 "CASTA�EDA"
在使用 bufio 阅读时,有什么方法可以处理这些字符?
谢谢。
您遇到的问题是您的输入可能不是 UTF-8(这是 bufio 和大多数 Go language/stdlib 所期望的)。相反,您的输入可能使用了一些扩展的 ASCII 代码页,这就是为什么不带重音的字符可以干净地通过(UTF-8 也是 7 位 ASCII 的超集),但是 'Ñ' 没有完整地通过。
在这种情况下,重音字符的位表示不是有效的 UTF-8,因此正在生成 unicode 替换字符 (U+FFFD)。您有几个选择:
- 将您的输入文件转换为 UTF-8,然后再将它们传递给 Go。有很多实用程序可以做到这一点,编辑器通常都有这个功能。
- 尝试使用 golang.org/x/text/encoding/charmap together with NewReader from golang.org/x/text/transform 将您的输入转换为 UTF-8。将结果 Reader 传递给 bufio.NewScanner
- 将循环中的行更改为
os.Stdout.Write(scanner.Bytes()); fmt.Println();
这可能会避免在换行符拆分之外将字节解释为 UTF-8。将字节直接写入 os.Stdout
将进一步避免对内容的任何(错误)解释。
您的文件很可能不是 UTF-8。因此(go 期望所有字符串都是 UTF-8)你的控制台输出看起来很乱。我建议在您的情况下使用 golang.org/x/text/encoding/charmap
和 golang.org/x/text/transform
包,将文件的数据转换为 UTF-8。正如我推测的那样,查看您的文件路径,您在 Windows 上。所以你的字符编码可能是 Windows1252
(如果你编辑过它,例如 notepad.exe)。
尝试这样的事情:
package main
import (
"bufio"
"fmt"
"log"
"os"
"golang.org/x/text/encoding/charmap"
"golang.org/x/text/transform"
)
func main() {
file, err := os.Open("C:/temp/file.txt")
defer file.Close()
if err != nil {
log.Fatal(err)
}
dec := transform.NewReader(file, charmap.Windows1252.NewDecoder()) <- insert your enconding here
scanner := bufio.NewScanner(dec)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
您可以在包 golang.org/x/text/encoding/charmap
中找到更多编码,您可以根据自己的喜好将其插入到我的示例中。
我正在尝试读取包含如下名称的纯文本文件:"CASTAÑEDA"
代码基本是这样的:
file, err := os.Open("C:/Files/file.txt")
defer file.Close()
if err != nil {
log.Fatal(err)
}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
然后,当读取 "CASTAÑEDA" 时,它会打印 "CASTA�EDA"
在使用 bufio 阅读时,有什么方法可以处理这些字符?
谢谢。
您遇到的问题是您的输入可能不是 UTF-8(这是 bufio 和大多数 Go language/stdlib 所期望的)。相反,您的输入可能使用了一些扩展的 ASCII 代码页,这就是为什么不带重音的字符可以干净地通过(UTF-8 也是 7 位 ASCII 的超集),但是 'Ñ' 没有完整地通过。
在这种情况下,重音字符的位表示不是有效的 UTF-8,因此正在生成 unicode 替换字符 (U+FFFD)。您有几个选择:
- 将您的输入文件转换为 UTF-8,然后再将它们传递给 Go。有很多实用程序可以做到这一点,编辑器通常都有这个功能。
- 尝试使用 golang.org/x/text/encoding/charmap together with NewReader from golang.org/x/text/transform 将您的输入转换为 UTF-8。将结果 Reader 传递给 bufio.NewScanner
- 将循环中的行更改为
os.Stdout.Write(scanner.Bytes()); fmt.Println();
这可能会避免在换行符拆分之外将字节解释为 UTF-8。将字节直接写入os.Stdout
将进一步避免对内容的任何(错误)解释。
您的文件很可能不是 UTF-8。因此(go 期望所有字符串都是 UTF-8)你的控制台输出看起来很乱。我建议在您的情况下使用 golang.org/x/text/encoding/charmap
和 golang.org/x/text/transform
包,将文件的数据转换为 UTF-8。正如我推测的那样,查看您的文件路径,您在 Windows 上。所以你的字符编码可能是 Windows1252
(如果你编辑过它,例如 notepad.exe)。
尝试这样的事情:
package main
import (
"bufio"
"fmt"
"log"
"os"
"golang.org/x/text/encoding/charmap"
"golang.org/x/text/transform"
)
func main() {
file, err := os.Open("C:/temp/file.txt")
defer file.Close()
if err != nil {
log.Fatal(err)
}
dec := transform.NewReader(file, charmap.Windows1252.NewDecoder()) <- insert your enconding here
scanner := bufio.NewScanner(dec)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
您可以在包 golang.org/x/text/encoding/charmap
中找到更多编码,您可以根据自己的喜好将其插入到我的示例中。