在 golang 编写器中删除连续的空行

我有一个渲染文件的 Go 文本/模板,但是我发现很难在保留输出中的换行符的同时干净地构建模板。


我想在模板中有额外的、不必要的换行符以使其更具可读性,但从输出中删除它们。任何超过正常分段符的换行符组都应该压缩为正常的分段符,例如


lines with




too many breaks should become lines with


normal paragraph breaks.

该字符串可能太大而无法安全地存储在内存中,因此我想将其保留为输出流。


我的第一次尝试:


type condensingWriter struct {

    writer io.Writer

    lastLineIsEmpty bool

}


func (c condensingWriter) Write(b []byte) (n int, err error){

    thisLineIsEmpty := strings.TrimSpace(string(b)) == ""

    defer func(){

        c.lastLineIsEmpty = thisLineIsEmpty

    }()

    if c.lastLineIsEmpty && thisLineIsEmpty{

        return 0, nil

    } else {

        return c.writer.Write(b)

    }

}

这不起作用,因为我天真地认为它会缓冲换行符,但事实并非如此。


有关如何使其工作的任何建议?


慕神8447489
浏览 336回答 2
2回答

繁星点点滴滴

一般的想法是您必须在输入切片中的任何位置查找连续的换行符,如果存在这种情况,请跳过除第一个换行符之外的所有内容。此外,您必须跟踪写入的最后一个字节是否为换行符,以便下次调用Write时知道是否需要删除换行符。通过bool在您的作家类型中添加一个,您走在正确的轨道上。但是,您需要在此处使用指针接收器而不是值接收器,否则您将修改结构的副本。你想改变func (c condensingWriter) Write(b []byte)到func (c *condensingWriter) Write(b []byte)你可以尝试像这样。您必须使用更大的输入进行测试,以确保它正确处理所有情况。package mainimport (&nbsp; &nbsp; "bytes"&nbsp; &nbsp; "io"&nbsp; &nbsp; "os")var Newline byte = byte('\n')type ReduceNewlinesWriter struct {&nbsp; &nbsp; w&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;io.Writer&nbsp; &nbsp; lastByteNewline bool}func (r *ReduceNewlinesWriter) Write(b []byte) (int, error) {&nbsp; &nbsp; // if the previous call to Write ended with a \n&nbsp; &nbsp; // then we have to skip over any starting newlines here&nbsp; &nbsp; i := 0&nbsp; &nbsp; if r.lastByteNewline {&nbsp; &nbsp; &nbsp; &nbsp; for i < len(b) && b[i] == Newline {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i++&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; b = b[i:]&nbsp; &nbsp; }&nbsp; &nbsp; r.lastByteNewline = b[len(b) - 1] == Newline&nbsp; &nbsp; i = bytes.IndexByte(b, Newline)&nbsp; &nbsp; if i == -1 {&nbsp; &nbsp; &nbsp; &nbsp; // no newlines - just write the entire thing&nbsp; &nbsp; &nbsp; &nbsp; return r.w.Write(b)&nbsp; &nbsp; }&nbsp; &nbsp; // write up to the newline&nbsp; &nbsp; i++&nbsp; &nbsp; n, err := r.w.Write(b[:i])&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return n, err&nbsp; &nbsp; }&nbsp; &nbsp; // skip over immediate newline and recurse&nbsp; &nbsp; i++&nbsp; &nbsp; for i < len(b) && b[i] == Newline {&nbsp; &nbsp; &nbsp; &nbsp; i++&nbsp; &nbsp; }&nbsp; &nbsp; i--&nbsp; &nbsp; m, err := r.Write(b[i:])&nbsp; &nbsp; return n + m, nil}func main() {&nbsp; &nbsp; r := ReduceNewlinesWriter{&nbsp; &nbsp; &nbsp; &nbsp; w: os.Stdout,&nbsp; &nbsp; }&nbsp; &nbsp; io.WriteString(&r, "this\n\n\n\n\n\n\nhas\nmultiple\n\n\nnewline\n\n\n\ncharacters")}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go