Python段落字符串格式化器

4 投票
3 回答
9285 浏览
提问于 2025-04-16 00:18

我正在尝试将一些字符串格式化,以便在命令行上以报告的形式输出,并且我想找到一种最简单的方法来格式化字符串,以便能够自动进行段落格式化。

在perl中,格式化是通过“format”这个函数来完成的。

format Something =
    Test: @<<<<<<<< @||||| @>>>>>
            $str,     $%,    '$' . int($num)
.

$str = "widget";
$num = $cost/$quantity;
$~ = 'Something';
write;

perl的格式化变体可以让文本整齐地换行,这对于帮助屏幕、日志报告等非常有用。

在Python中有没有类似的功能?或者我能用Python的新字符串format函数写出一个合理的解决方案吗?

我想要的输出示例是:

Foobar-Title    Blob
  0123          This is some long text which would wrap
                past the 80 column mark and go onto the
                next line number of times blah blah blah.
  hi there      dito
  something     more text here. more text here. more text
                here.

3 个回答

1

这里有一些来自Python文档的内容,你可以查看这个链接,还有这个链接,可能会对你有帮助。

4
import textwrap
import itertools

def formatter(format_str,widths,*columns):
    '''
    format_str describes the format of the report.
    {row[i]} is replaced by data from the ith element of columns.

    widths is expected to be a list of integers.
    {width[i]} is replaced by the ith element of the list widths.

    All the power of Python's string format spec is available for you to use
    in format_str. You can use it to define fill characters, alignment, width, type, etc.

    formatter takes an arbitrary number of arguments.
    Every argument after format_str and widths should be a list of strings.
    Each list contains the data for one column of the report.

    formatter returns the report as one big string.
    '''
    result=[]
    for row in zip(*columns):
        lines=[textwrap.wrap(elt, width=num) for elt,num in zip(row,widths)]
        for line in itertools.izip_longest(*lines,fillvalue=''):
            result.append(format_str.format(width=widths,row=line))
    return '\n'.join(result)

比如说:

widths=[17,41]
form='{row[0]:<{width[0]}} {row[1]:<{width[1]}}'

titles=['Foobar-Title','0123','hi there','something']
blobs=['Blob','This is some long text which would wrap past the 80 column mark and go onto the next line number of times blah blah blah.','dito','more text here. more text here. more text here.']

print(formatter(form,widths,titles,blobs))

会得到

# Foobar-Title      Blob                                     
# 0123              This is some long text which would wrap  
#                   past the 80 column mark and go onto the  
#                   next line number of times blah blah blah.
# hi there          dito                                     
# something         more text here. more text here. more text
#                   here.                                    

formatter 可以处理任意数量的列。

6

Python里面没有像这样自动格式化的功能。(.format函数的语法是借鉴自C#的。)毕竟,Perl的全名是“实用提取和报告语言”,而Python并不是为了格式化报告而设计的。

你可以使用textwrap模块来实现你的输出,比如:

from textwrap import fill
def formatItem(left, right):
   wrapped = fill(right, width=41, subsequent_indent=' '*15)
   return '  {0:<13}{1}'.format(left, wrapped)

...

>>> print(formatItem('0123', 'This is some long text which would wrap past the 80 column mark and go onto the next line number of times blah blah blah.'))
  0123         This is some long text which would wrap
               past the 80 column mark
               and go onto the next line
               number of times blah blah
               blah.

注意,这里假设“左边”的内容不会超过一行。如果想要一个更通用的解决方案,可以参考:

from textwrap import wrap
from itertools import zip_longest
def twoColumn(left, right, leftWidth=13, rightWidth=41, indent=2, separation=2):
    lefts = wrap(left, width=leftWidth)
    rights = wrap(right, width=rightWidth)
    results = []
    for l, r in zip_longest(lefts, rights, fillvalue=''):
       results.append('{0:{1}}{2:{5}}{0:{3}}{4}'.format('', indent, l, separation, r, leftWidth))
    return "\n".join(results)

>>> print(twoColumn("I'm trying to format some strings for output on the command-line", "report style, and am looking for the easiest method to format a string such that I can get automatic paragraph formatting."))
  I'm trying to  report style, and am looking for the
  format some    easiest method to format a string such
  strings for    that I can get automatic paragraph
  output on the  formatting.
  command-line   

撰写回答