Python Textwrap - 强制“硬”换行

2 投票
2 回答
1377 浏览
提问于 2025-04-15 22:53

我正在尝试使用textwrap来格式化一个对格式要求很严格的导入文件。基本上,它的格式是这样的(为了简单起见,行长度缩短了):

abcdef <- Ok line
abcdef 
 ghijk <- Note leading space to indicate wrapped line
 lm

现在,我已经写了一段代码,效果如下:

wrapper = TextWrapper(width=80, subsequent_indent=' ', break_long_words=True, break_on_hyphens=False)
for l in lines:
  wrapline=wrapper.wrap(l)

这个代码几乎完美地工作了,不过,文本换行的部分没有在80个字符的位置进行硬性换行,而是试图智能地在空格处换行(大约在20个字符的位置)。

我通过把字符串列表中的所有空格替换成一个独特的字符(#),然后进行换行,最后再把这个字符去掉,解决了这个问题,但肯定还有更简单的方法吧?

注意:任何可能的解决方案需要在Python 2.4上运行——抱歉!

2 个回答

1

听起来你是在关闭TextWrapper的大部分功能,然后试图添加一点自己的东西。我觉得你不如自己写一个函数或者类。如果我理解得没错,你只是想找出超过80个字符的行,然后在80个字符的地方断开,并且把剩下的部分缩进一个空格。

比如,这段代码:

s = """\
This line is fine.
This line is very long and should wrap, It'll end up on a few lines.
A short line.
"""

def hard_wrap(s, n, indent):
    wrapped = ""
    n_next = n - len(indent)
    for l in s.split('\n'):
        first, rest = l[:n], l[n:]
        wrapped += first + "\n"
        while rest:
            next, rest = rest[:n_next], rest[n_next:]
            wrapped += indent + next + "\n"
    return wrapped

print hard_wrap(s, 20, " ")

会产生:

This line is fine.
This line is very lo
 ng and should wrap,
  It'll end up on a
 few lines.
A short line.
1

基于生成器的版本可能对你来说是个更好的解决方案,因为它不需要一次性把整个字符串加载到内存中:

def hard_wrap(input, width, indent=' '):
   for line in input:
      indent_width = width - len(indent)
      yield line[:width]
      line = line[width:]
      while line:
         yield '\n' + indent + line[:indent_width]
         line = line[indent_width:]

你可以这样使用它:

from StringIO import StringIO # Makes strings look like files

s = """abcdefg
abcdefghijklmnopqrstuvwxyz"""

for line in hard_wrap(StringIO(s), 12):
   print line,

这会输出:

abcdefg
abcdefghijkl 
 mnopqrstuvw 
 xyz

撰写回答