Библиотека textwrap Python — как сохранить разрывы строк?

Как я могу включить это при использовании библиотеки textwrap Python:

short line,

long line xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

в это:

short line,

long line xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxx

Я старался:

w = textwrap.TextWrapper(width=90,break_long_words=False)
body = '\n'.join(w.wrap(body))

Но я получаю:

short line, long line xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

(интервал не точен в моих примерах)


person Greg    schedule 22.07.2009    source источник


Ответы (6)


пытаться

w = textwrap.TextWrapper(width=90,break_long_words=False,replace_whitespace=False)

это, казалось, решило проблему для меня

Я понял это из того, что прочитал здесь (я никогда не использовал обтекание текстом раньше)

person Peter    schedule 22.07.2009
comment
Имейте в виду, что в этом случае оболочка рассматривает \n как символ, а не как разрыв строки, например, она будет считать, что ранее\nопубликовано одно слово. Во многих случаях это вызывает проблемы с форматированием. Таким образом, решение с \n.join(), предоставленное пользователем, намного лучше. - person Zulko; 21.02.2015

Как насчет переноса только строк длиннее 90 символов?

new_body = ""
lines = body.split("\n")

for line in lines:
    if len(line) > 90:
        w = textwrap.TextWrapper(width=90, break_long_words=False)
        line = '\n'.join(w.wrap(line))

    new_body += line + "\n"
person tefozi    schedule 22.07.2009

Вроде не поддерживает. Этот код расширит его, чтобы делать то, что мне нужно:

http://code.activestate.com/recipes/358228/

person Greg    schedule 22.07.2009

Вот небольшой модуль, который может переносить текст, разрывать строки, обрабатывать дополнительные отступы (например, маркированный список) и заменять символы/слова уценкой!

class TextWrap_Test:
    def __init__(self):
        self.Replace={'Sphagnum':'$Sphagnum$','Equisetum':'$Equisetum$','Carex':'$Carex$',
                      'Salix':'$Salix$','Eriophorum':'$Eriophorum$'}
    def Wrap(self,Text_to_fromat,Width):
        Text = []
        for line in Text_to_fromat.splitlines():
            if line[0]=='-':
                wrapped_line = textwrap.fill(line,Width,subsequent_indent='  ')
            if line[0]=='*':
                wrapped_line = textwrap.fill(line,Width,initial_indent='  ',subsequent_indent='    ')
            Text.append(wrapped_line)
        Text = '\n\n'.join(text for text in Text)

        for rep in self.Replace:
            Text = Text.replace(rep,self.Replace[rep])
        return(Text)


Par1 = "- Fish Island is a low center polygonal peatland on the transition"+\
" between the Mackenzie River Delta and the Tuktoyaktuk Coastal Plain.\n* It"+\
" is underlain by continuous permafrost, peat deposits exceede the annual"+\
" thaw depth.\n* Sphagnum dominates the polygon centers with a caonpy of Equisetum and sparse"+\
" Carex.  Dwarf Salix grows allong the polygon rims.  Eriophorum and carex fill collapsed ice wedges."
TW=TextWrap_Test()
print(TW.Wrap(Par1,Text_W))

Выведет:

  • Фиш-Айленд представляет собой многоугольный торфяник с низким центром на переходе между дельтой реки Маккензи и прибрежной равниной Туктояктук.

    • Под ним сплошная многолетняя мерзлота, торфяные отложения превышают годовую глубину протаивания.

    • В центрах полигонов преобладает $Sphagnum$ с составом $Equisetum$ и редким $Carex$. Карлик $Salix$ растет по краям полигона. $Eriophorum$ и carex заполняют обрушившиеся жилы льда.

Символы между $$ будут выделены курсивом, если вы, например, работали в matplotlib, но $$ не будут учитываться в межстрочном интервале, поскольку они добавляются после!

Итак, если вы сделали:

fig,ax = plt.subplots(1,1,figsize = (10,7))
ax.text(.05,.9,TW.Wrap(Par1,Text_W),fontsize = 18,verticalalignment='top')

ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)

Вы получите: введите здесь описание изображения

person June Skeeter    schedule 07.04.2018
comment
спасибо часть вас и помочь мне решить мою проблему! - person sayalok; 12.09.2019

У меня была аналогичная проблема с форматированием динамически генерируемых строк документации. Я хотел сохранить введенные вручную новые строки, и разделить все строки определенной длины. Немного переработав ответ @far, это решение сработало для меня. Я включаю его сюда только для потомков:

import textwrap

wrapArgs = {'width': 90, 'break_long_words': True, 'replace_whitespace': False}
fold = lambda line, wrapArgs: textwrap.fill(line, **wrapArgs)
body = '\n'.join([fold(line, wrapArgs) for line in body.splitlines()])
person Lex Scarisbrick    schedule 24.08.2016

TextWrapper не предназначен для обработки текста, в котором уже есть новые строки.

Есть две вещи, которые вы можете сделать, когда в вашем документе уже есть символы новой строки:

1) Сохраняйте старые символы новой строки и переносите только те строки, которые длиннее установленного ограничения.

Вы можете создать подкласс TextWrapper следующим образом:

class DocumentWrapper(textwrap.TextWrapper):

    def wrap(self, text):
        split_text = text.split('\n')
        lines = [line for para in split_text for line in textwrap.TextWrapper.wrap(self, para)]
        return lines

Затем используйте его так же, как textwrap:

d = DocumentWrapper(width=90)
wrapped_str = d.fill(original_str)

Дает тебе:

short line,
long line xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxx

2) Удалите старые символы новой строки и оберните все.

original_str.replace('\n', '')
wrapped_str = textwrap.fill(original_str, width=90)

Дает тебе

short line,  long line xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

(TextWrapper не делает ни того, ни другого — он просто игнорирует существующие символы новой строки, что приводит к странному форматированию результата)

person Peter    schedule 24.07.2017