一、Scanner是什么?
Scanner为读取数据提供了一些方便的接口,通过切割方法可以逐字节,逐字,逐词组,逐行读取,某些场景下使用scanner可以很方便的解决问题。
二、使用
func main() {
s := strings.NewReader("Hello world")
bs := bufio.NewScanner(s)
bs.Split(bufio.ScanBytes)
for bs.Scan() {
fmt.Printf("%s \n", bs.Text())
}
}
Scanner中的Split接收切割函数,底下的结果都将只更换bs.Split(bufio.ScanBytes)中的ScanBytes为底下的函数。
1.ScanBytes
该函数将内容切分成单个字节返回
结果:
H
e
l
l
o
w
o
r
l
d
注意该函数碰到多字节的输出将无意义
2.ScanWords
该函数将按空格或者换行符区分
结果:
Hello
world
3.ScanRunes
该函数将逐字返回,且多字节(如中文)不会乱码
结果:
H
e
l
l
o
世
界
4.ScanLines
该函数将按行返回
代码如下:
func main() {
s := strings.NewReader("Hello 世界\nhaha")
bs := bufio.NewScanner(s)
bs.Split(bufio.ScanLines)
for bs.Scan() {
fmt.Printf("%s \n", bs.Text())
}
}
结果:
Hello 世界
haha
5.自定义Split
自定义Split可以在里面增加一些限制条件用来限制函数的返回结果
代码如下:
func main() {
const input = "1234 5678 1234567901234567"
scanner := bufio.NewScanner(strings.NewReader(input))
split := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
advance, token, err = bufio.ScanWords(data, atEOF)
if err == nil && token != nil {
_, err = strconv.ParseInt(string(token), 10, 32)
}
return
}
scanner.Split(split)
for scanner.Scan() {
fmt.Printf("%s \n", scanner.Text())
}
}
该函数中,第三部分的数字是没有办法通过转换的,所以将不会返回出去
结果:
1234
5678