为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕神8447489 2021-09-13 15:38:55
我有一个渲染文件的 Go 文本/模板,但是我发现很难在保留输出中的换行符的同时干净地构建模板。我想在模板中有额外的、不必要的换行符以使其更具可读性,但从输出中删除它们。任何超过正常分段符的换行符组都应该压缩为正常的分段符,例如lines withtoo many breaks should become lines withnormal 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)    }}这不起作用,因为我天真地认为它会缓冲换行符,但事实并非如此。有关如何使其工作的任何建议?
查看完整描述

2 回答

?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

一般的想法是您必须在输入切片中的任何位置查找连续的换行符,如果存在这种情况,请跳过除第一个换行符之外的所有内容。


此外,您必须跟踪写入的最后一个字节是否为换行符,以便下次调用Write时知道是否需要删除换行符。通过bool在您的作家类型中添加一个,您走在正确的轨道上。但是,您需要在此处使用指针接收器而不是值接收器,否则您将修改结构的副本。


你想改变


func (c condensingWriter) Write(b []byte)


func (c *condensingWriter) Write(b []byte)

你可以尝试像这样。您必须使用更大的输入进行测试,以确保它正确处理所有情况。


package main


import (

    "bytes"

    "io"

    "os"

)


var Newline byte = byte('\n')


type ReduceNewlinesWriter struct {

    w               io.Writer

    lastByteNewline bool

}


func (r *ReduceNewlinesWriter) Write(b []byte) (int, error) {

    // if the previous call to Write ended with a \n

    // then we have to skip over any starting newlines here

    i := 0

    if r.lastByteNewline {

        for i < len(b) && b[i] == Newline {

            i++

        }

        b = b[i:]

    }

    r.lastByteNewline = b[len(b) - 1] == Newline


    i = bytes.IndexByte(b, Newline)

    if i == -1 {

        // no newlines - just write the entire thing

        return r.w.Write(b)

    }

    // write up to the newline

    i++

    n, err := r.w.Write(b[:i])

    if err != nil {

        return n, err

    }


    // skip over immediate newline and recurse

    i++


    for i < len(b) && b[i] == Newline {

        i++

    }

    i--

    m, err := r.Write(b[i:])

    return n + m, nil

}


func main() {

    r := ReduceNewlinesWriter{

        w: os.Stdout,

    }

    io.WriteString(&r, "this\n\n\n\n\n\n\nhas\nmultiple\n\n\nnewline\n\n\n\ncharacters")

}


查看完整回答
反对 回复 2021-09-13
  • 2 回答
  • 0 关注
  • 335 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信