登录
首页 >  Golang >  Go问答

获取包含换行符在内的行的长度时如何使用Scanner?

来源:stackoverflow

时间:2024-03-23 18:15:28 319浏览 收藏

使用 Scanner 时,无法获取包含换行符的行的长度,因为 Scanner 会自动删除换行符。相反,可以使用自定义拆分函数,例如 scanlines,来移植到不会删除换行符的函数。

问题内容

我正在使用 scan 从 imap 连接一次扫描第 1 行,这些行应该以 \r\n 结尾,但我怀疑我得到的一些行实际上只是以 \ 结尾n,因为在特定实例中解析主体原子时我得到的数据量不正确

* 8620 fetch(body[] {7060} 是我在这一封电子邮件中获得的正文,但如果将换行符计为 2 个字节,则这似乎比计数要长)

// ...
r := bufio.NewScanner(d.conn)
for r.Scan() {
    line := r.Text()
    len(line) // gets the line length WITHOUT the newline
}

有什么办法可以获取换行符的长度吗?或者获取扫描仪停止的令牌的长度?


解决方案


虽然这个答案从字面意义上回答了我关于包含 \n 和潜在 \r 的问题,但在读取 imap 服务器响应时首先使用扫描仪并不是正确的工具,我会重写我对扫描仪的使用并将其替换为 bufio.reader。

您可以指定在扫描程序中使用的自定义拆分函数,例如,您可以将 scanlines 拆分函数移植到不会使用返回的令牌删除换行符的函数。

// ...
r := bufio.NewScanner(d.conn)
r.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
    if atEOF && len(data) == 0 {
        return 0, nil, nil
    }
    if i := bytes.IndexByte(data, '\n'); i >= 0 {
        // We have a full newline-terminated line.
        return i + 1, data[0 : i+1], nil
    }
    // If we're at EOF, we have a final, non-terminated line. Return it.
    if atEOF {
        return len(data), data, nil
    }
    // Request more data.
    return 0, nil, nil
})

for r.Scan() {
    line := r.Text()
    len(line) // now gets the line length WITH the newline
}

提供给 bufio.newscanner 的默认 splitfuncsplitlines,其中包括对 dropcr 的调用,根据注释,该调用在行尾 \r?\nzqbendcz 上匹配qb。由于 scanner 将选择性地查找并删除回车符,因此您将无法使用 bufio.scanner 查找行的完整长度。

根据我的经验,当事情很基本时,通常使用扫描仪,因为它是一个方便的结构。否则 bufio.reader 提供了更大的灵活性。 bufio.reader#readbytes(delim byte) 会给你你正在寻找的东西。

本篇关于《获取包含换行符在内的行的长度时如何使用Scanner?》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>