Python Textwrap - 强制“硬”休息

发布于 2024-09-01 23:41:12 字数 555 浏览 7 评论 0原文

我正在尝试使用 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 上工作 - 抱歉!

I am trying to use textwrap to format an import file that is quite particular in how it is formatted. Basically, it is as follows (line length shortened for simplicity):

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

Now, I have got code to work as follows:

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

This works nearly perfectly, however, the text wrapping code doesn't do a hard break at the 80 character mark, it tries to be smart and break on a space (at approx 20 chars in).

I have got round this by replacing all spaces in the string list with a unique character (#), wrapping them and then removing the character, but surely there must be a cleaner way?

N.B Any possible answers need to work on Python 2.4 - sorry!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

楠木可依 2024-09-08 23:41:12

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

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

A generator-based version might be a better solution for you, since it wouldn't need to load the entire string in memory at once:

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:]

Use it like this:

from StringIO import StringIO # Makes strings look like files

s = """abcdefg
abcdefghijklmnopqrstuvwxyz"""

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

Which prints:

abcdefg
abcdefghijkl 
 mnopqrstuvw 
 xyz
焚却相思 2024-09-08 23:41:12

听起来您正在禁用 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.

It sounds like you are disabling most of the functionality of TextWrapper, and then trying to add a little of your own. I think you'd be better off writing your own function or class. If I understand you right, you're simply looking for lines longer than 80 chars, and breaking them at the 80-char mark, and indenting the remainder by one space.

For example, this:

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, " ")

produces:

This line is fine.
This line is very lo
 ng and should wrap,
  It'll end up on a
 few lines.
A short line.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文