英文:
Can i pass a string as a delimiter for bufio.ReadString()?
问题
我有一个包含多行查询的文件。我想逐行读取并打印它们。类似这样:
temp.sql
select * from table1;
select *
from table2;
select 1;
由于我可能有多行查询,我想使用";\n"作为分隔符。这种方法可行吗?有没有比bufio.ReadString
更好的方法?
英文:
I have a file which contains multi-line queries. I wanted to read them one by one and print them. Something like :
temp.sql
select * from table1;
select *
from table2;
select 1;
Since i can have multiline queries I wanted to use ;\n as the delimiter. Is that possible ? Is there a better method that i can use instead of bufio.ReadString
?
答案1
得分: 7
首先,bufio.ReadString
的原型是:
func (b *Reader) ReadString(delim byte) (line string, err error)
它只能接受一个字节作为参数,所以你的 ;\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;"
解决方案:
使用 Scanner
可能更方便,并且可以实现如下效果。
注意:;
将被视为单词的一部分。
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;
英文:
firstly, the prototype of bufio.ReadString
is
func (b *Reader) ReadString(delim byte) (line string, err error)
it can only take one byte as arg, so your ;\n
delimiter won't work.
use ;
as delimiter instead.
But if you use ReadString(';')
it will contain other characters in your results, such as '\n'
a example:
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)
}
}
this will get:
"select * from table1;"" \nselect * \nfrom table2;""\n\nselect 1;"
Solution:
use Scanner
may be more convenient, and achieve this as bellow.
ps: ;
will be considered as part of words
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)
}
}
you will get:
select * from table1;
select * from table2;
select 1;
答案2
得分: 2
你可以使用bufio.Scanner
来实现这个功能:https://golang.org/pkg/bufio/#Scanner
可以参考这个示例代码:https://golang.org/pkg/bufio/#example_Scanner_lines
英文:
You can use bufio.Scanner
for that: https://golang.org/pkg/bufio/#Scanner
See the lines example: https://golang.org/pkg/bufio/#example_Scanner_lines
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论