如何在`textwrap.fill`中保留双换行?

3 投票
1 回答
1053 浏览
提问于 2025-04-18 12:23

我有一段文本,这段文本由几个段落组成,段落之间用两个换行符分开。我想把这些段落格式化成每行70个字符宽,同时保留换行符,并且整个文本应该以一行不缩进的方式开始,内容是 Abstract: Lorem ipsum ...

所以最终的效果应该是这样的:

Abstract: Magna risus nonummy mollis mattis neque commodo mattis fusce  
          hendrerit nibh. Lorem massa lorem mauris ad orci quam risus
          viverra aliquet senectus sociis. Donec proin nam dolor neque
          placerat imperdiet eros ullamcorper egestas cum torquent
          habitasse. Risus donec odio nostra ac et pede inceptos
          praesent montes. Neque morbi sit morbi vestibulum
          suspendisse mauris. Lacus massa mollis.

          Donec class integer pede ac sed elit. Fames augue magnis
          sapien natoque nisi. Proin augue mus nisl interdum convallis
          pellentesque conubia.

          Class dolor tempor netus suspendisse odio orci
          vestibulum mus. Netus purus. Lacus metus tempor purus
          adipiscing faucibus eget maecenas. Velit lacus integer
          rhoncus primis nunc quis lorem lacus dictumst hendrerit.

我尝试使用 textwrap,但结果并不是我想要的。以下是我的代码:

from loremipsum import get_paragraphs
import textwrap

text = '\n\n'.join(get_paragraphs(3))
item = 'Abstract: '

print textwrap.fill(item+text,initial_indent='',subsequent_indent=' '*len(item),replace_whitespace=False)

这段代码对第一个段落效果很好,但后面的段落却出现了一些奇怪的缩进和短行,像这样:

Class vitae
          nonummy imperdiet cras blandit fusce. Massa porta metus
          semper tempor non id viverra eget. Purus morbi lorem semper
          eget. Proin magna tortor metus magnis. Vitae ipsum. Velit
          class aliquet tortor dolor parturient ullamcorper libero ac.

即使我使用 initial_indent=' '*len(item),也会出现这个问题。这是个bug吗?我该怎么才能得到我想要的效果呢?

1 个回答

4

来自文档的说明:

注意:如果 replace_whitespace 设置为假,那么在一行的中间可能会出现换行符,这样会导致输出看起来很奇怪。因此,文本应该被分成段落(可以使用 str.splitlines() 或类似的方法),并且每个段落要单独处理。

所以你应该这样做:

paragraphs = get_paragraphs(3)
item = 'Abstract: '
paragraphs[0] = item + paragraphs[0]
for idx, paragraph in enumerate(paragraphs):
    rest_indent = " "*len(item)
    start_indent = "" if idx == 0 else rest_indent
    print textwrap.fill(paragraph,initial_indent=start_indent,subsequent_indent=rest_indent,replace_whitespace=False)
    print ""

另外,你也可以使用列表推导式来实现:

paragraphs = get_paragraphs(3)
item = 'Abstract: '
text = "\n\n".join(textwrap.fill(p,initial_indent=' '*len(item),subsequent_indent=' '*len(item)) for p in paragraphs)
print item + text.lstrip()

撰写回答