我可以传递一个字符串作为bufio.ReadString()的分隔符吗?

时间:2016-01-15 01:41:52

标签: go

我有一个包含多行查询的文件。我想逐个阅读它们并打印出来。类似的东西:

temp.sql

select * from table1;  
select *  
from table2;

select 1; 

因为我可以使用多行查询; \ n作为分隔符。那可能吗 ?有没有更好的方法可以使用而不是bufio.ReadString

2 个答案:

答案 0 :(得分:4)

首先,bufio.ReadString的原型是

 func (b *Reader) ReadString(delim byte) (line string, err error)

只能将一个字节作为arg,因此;\n分隔符将无效。

改为使用;作为分隔符。

但如果您使用ReadString(';'),则结果中会包含其他字符,例如'\ n'

一个例子:

package main

import (
    "bufio"
    "fmt"
    "strings"
)

func main() {

    const raw = `select * from table1;  
select *  
from table2;

select 1;`

    br := bufio.NewReader(strings.NewReader(raw))

    var err error
    var s string
    err = nil
    for err == nil {
        s, err = br.ReadString(';')
        if err == nil {
            fmt.Printf("%q", s)
        }

    }

这将得到:

"select * from table1;""  \nselect *  \nfrom table2;""\n\nselect 1;"

online test

<强>解决方案:

使用Scanner可能更方便,并且如下所示实现此目的。

ps:;将被视为单词的一部分

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
    "bytes"
)

func main() {
    const raw = `select * from table1;  
select *  
from table2;

select 1;`

    scanner := bufio.NewScanner(strings.NewReader(raw))
    scanner.Split(bufio.ScanWords)

    var tmpbuf bytes.Buffer

    for scanner.Scan() {
        w := scanner.Text()
        tmpbuf.WriteString(w)
        if w[len(w)-1] == ';' {
            tmpbuf.WriteString("\n")
            fmt.Printf(tmpbuf.String())
            tmpbuf.Reset()
        } else {
            tmpbuf.WriteString(" ")
        }
    }
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "reading input:", err)
    }
}

你会得到:

select * from table1;
select * from table2;
select 1;

online test

答案 1 :(得分:1)