Python3標准庫:textwrap文本自動換行與填充


1. textwrap文本自動換行與填充

textwrap模塊提供了一些快捷函數,以及可以完成所有工作的類TextWrapper。如果你只是要對一兩個文本字符串進行自動或填充,快捷函數應該就夠用了;否則的話,你應該使用TextWrapper的實例來提高效率。

1.1 填充段落

textwrap.fill(text,width=70,**kwargs)

  對text中的單獨段落自動換行,並返回一個包含被自動換行段落的單獨字符串。fill()以下語句的快捷方式。

"\n".join(wrap(text, ...))

特別要說明的是,fill()接受與wrap()完全相同的關鍵字參數。

import textwrap

sample_text = '''
    The textwrap module can be used to format text for output in
    situations where pretty-printing is desired.  It offers
    programmatic functionality similar to the paragraph wrapping
    or filling features found in many text editors.
    '''
print(textwrap.fill(sample_text, width=50))

結果:

結果差強人意。文本現在左對齊,不過只有第一行保留了縮進,后面各行前面的空格都嵌入到段落中。 

1.2 去除現有的縮進

textwrap.dedent(text)

  移除text中每一行的任何相同前綴空白符。

  這可以用來清除三重引號字符串行左側空格,而仍然在源碼中顯示為縮進格式。

  請注意制表符和空格符都被視為是空白符,但它們並不相等:以下兩行

  "  hello"和"\thello"不會被視為具有相同的前綴空白符。

  只包含空白符的行會在輸入時被忽略並在輸出時被標准化為單個換行符。

import textwrap

sample_text = '''
    The textwrap module can be used to format text for output in
    situations where pretty-printing is desired.  It offers
    programmatic functionality similar to the paragraph wrapping
    or filling features found in many text editors.
    ''' dedented_text = textwrap.dedent(sample_text) print('Dedented:') print(dedented_text)

結果:

結果看起來更好。 

由於“dedent”(去除縮進)與“indent”(縮進)正好相反,所以結果將得到一個文本塊,其中每一行前面的空白符已經刪除。如果一行比另一行縮進更多,有些空白符則不會被刪除。  

1.3 結合dedent和fill

接下來可以把去除縮進的文本傳入fill(),並指定一些不同的width值。

import textwrap

sample_text = '''
    The textwrap module can be used to format text for output in
    situations where pretty-printing is desired.  It offers
    programmatic functionality similar to the paragraph wrapping
    or filling features found in many text editors.
    '''
dedented_text = textwrap.dedent(sample_text).strip()
for width in [45, 60]:
    print('{} Columns:\n'.format(width))
    print(textwrap.fill(dedented_text, width=width))
    print()

這會生成指定寬度的輸出。

1.4 縮進塊

textwrap.indent(text,profix,predicate=None) 

  將prefix添加到text中選定行的開頭。

  通過調用text.splitlines(True)來對行進行拆分。

  默認情況下,prefix會被添加到所有不是只由空白符(包括任何行結束符)組成的行。

  可選的predicate參數可用來控制哪些行要縮進。

  3.3新版功能。

使用>作為每一行的前綴。

import textwrap

sample_text = '''
    The textwrap module can be used to format text for output in
    situations where pretty-printing is desired.  It offers
    programmatic functionality similar to the paragraph wrapping
    or filling features found in many text editors.
    '''
dedented_text = textwrap.dedent(sample_text)
wrapped = textwrap.fill(dedented_text, width=50)
wrapped += '\n\nSecond paragraph after a blank line.'
final = textwrap.indent(wrapped, '> ')

print('Quoted block:\n')
print(final)

文本塊按換行符分解,將為包含文本的各行增加前綴,然后再把這些行合並為一個新字符串並返回。

為了控制哪些行接收新前綴,可以傳入一個callable對象作為indent()的predicate參數。會一次為各行文本調用這個callable,並為返回值為true的行添加前綴。

import textwrap

sample_text = '''
    The textwrap module can be used to format text for output in
    situations where pretty-printing is desired.  It offers
    programmatic functionality similar to the paragraph wrapping
    or filling features found in many text editors.
    '''
def should_indent(line):
    print('Indent {!r}?'.format(line))
    return len(line.strip()) % 2 == 0

dedented_text = textwrap.dedent(sample_text)
wrapped = textwrap.fill(dedented_text, width=50)
final = textwrap.indent(wrapped, 'EVEN ',
                        predicate=should_indent)

print('\nQuoted block:\n')
print(final)

這個例子會為包含偶數個字符的行添加前綴EVEN 。

1.5 懸掛縮進

不僅可以設置輸出的寬度,還可以采用相同的方式單獨控制首行的縮進,使首行的縮進不同於后續的各行。

import textwrap

sample_text = '''
    The textwrap module can be used to format text for output in
    situations where pretty-printing is desired.  It offers
    programmatic functionality similar to the paragraph wrapping
    or filling features found in many text editors.
    '''
dedented_text = textwrap.dedent(sample_text).strip()
print(textwrap.fill(dedented_text,
                    initial_indent='',
                    subsequent_indent=' ' * 4,
                    width=50,
                    ))

這就允許生成懸掛縮進,即首行縮進小於其他行的縮進。

縮進值也可以包含非空白字符。 

1.6 截斷長文本

textwrap.shorten(text,width,**kwargs) 

  折疊並截斷給定的text以符合給定的width。

  首先將折疊text中的空格(所有連續空格替換為單個空格)。 如果結果能適合width則將其返回。 否則將丟棄足夠數量的末尾單詞以使得剩余單詞加placeholder能適合width。   

import textwrap

sample_text = '''
    The textwrap module can be used to format text for output in
    situations where pretty-printing is desired.  It offers
    programmatic functionality similar to the paragraph wrapping
    or filling features found in many text editors.
    '''
dedented_text = textwrap.dedent(sample_text)
original = textwrap.fill(dedented_text, width=50)

print('Original:\n')
print(original)

shortened = textwrap.shorten(original, 100)
shortened_wrapped = textwrap.fill(shortened, width=50)

print('\nShortened:\n')
print(shortened_wrapped)

如果從原文本將非空白文本作為截斷部分刪除,那么它會被替換為一個占位值。可以為shorten()提供參數placeholder來替代默認值[...]

1.7 TextWrapper

wrap(),fill()和shorten()的作用方式為創建一個TextWrapper實例並在其上調用單個方法。該實例不會被重用,因此對於要使用wrap()和/或fill()來處理許多文本字符串的應用來說,創建你自己的TextWrapper對象可能會更有效率。

文本最好在空白符位置自動換行,包括帶連字符單詞的連字符之后;長單詞僅在必要時會被拆分,除非TextWrapper.break_long_words被設為假值。

class textwrap.TextWrapper(**kwargs)

TextWrapper構造器接收多個可選的關鍵字參數。每個關鍵字參數對應一個實例屬性,比如說

wrapper = TextWrapper(initial_indent="* ")

就相當於

wrapper = TextWrapper()
wrapper.initial_indent = "* "

你可以多次重用相同的TextWrapper對象,並且你也可以在使用期間通過直接向實例屬性賦值來修改它的任何選項。

TextWrapper的實例屬性(以及構造器的關鍵字參數)如下所示:

width

  (默認: 70) 自動換行的最大行長度。 只要輸入文本中沒有長於width的單個單詞,TextWrapper就能保證沒有長於width個字符的輸出行。

expand_tabs

  (默認: True) 如果為真值,則text中所有的制表符將使用text的expandtabs()方法擴展為空格符。

tabsize

(默認: 8) 如果expand_tabs為真值,則text中所有的制表符將擴展為零個或多個空格,具體取決於當前列位置和給定的制表寬度。

  3.3 新版功能.

replace_whitespace

  (default: True) 如果為真值,在制表符擴展之后、自動換行之前,wrap()方法將把每個空白字符都替換為單個空格。 會被替換的空白字符如下:制表,換行,垂直制表,進紙和回車 ('\t\n\v\f\r')。

注解:如果 expand_tabs 為假值且 replace_whitespace 為真值,每個制表符將被替換為單個空格,這與制表符擴展是  一樣的。

注解:如果 replace_whitespace 為假值,在一行的中間有可能出現換行符並導致怪異的輸出。 因此,文本應當(使用 str.splitlines() 或類似方法)拆分為段落並分別進行自動換行。

drop_whitespace

  (默認: True) 如果為真值,每一行開頭和末尾的空白字符(在包裝之后、縮進之前)會被丟棄。 但是段落開頭的空白字符如果后面不帶任何非空白字符則不會被丟棄。 如果被丟棄的空白字符占據了一個整行,則該整行將被丟棄。

initial_indent

  (默認: '') 將被添加到被自動換行輸出內容的第一行的字符串。 其長度會被計入第一行的長度。 空字符串不會被縮進。

subsequent_indent

  (默認: '') 將被添加到被自動換行輸出內容除第一行外的所有行的字符串。 其長度會被計入除行一行外的所有行的長度。

fix_sentence_endings

  (默認: False) 如果為真值,TextWrapper將嘗試檢測句子結尾並確保句子間總是以恰好兩個空格符分隔。 對於使用等寬字體的文本來說通常都需要這樣。 但是,句子檢測算法並不完美:它假定句子結尾是一個小寫字母加字符 '.''!' 或 '?' 中的一個,並可能帶有字符 '"' 或 "'",最后以一個空格結束。 此算法的問題之一是它無法區分以下文本中的 "Dr."

[...] Dr. Frankenstein's monster [...]

和以下文本中的 "Spot."

[...] See Spot. See Spot run [...]

fix_sentence_endings默認為假值。

  由於句子檢測算法依賴於string.lowercase來確定“小寫字母”,以及約定在句點后使用兩個空格來分隔處於同一行的句子,因此只適用於英語文本。

break_long_words

  (默認: True) 如果為真值,則長度超過width的單詞將被分開以保證行的長度不會超過width。如果為假值,超長單詞不會被分開,因而某些行的長度可能會超過width。 (超長單詞將被單獨作為一行,以盡量減少超出width的情況。)

break_on_hyphens

  (默認: True) 如果為真值,將根據英語的慣例首選在空白符和復合詞的連字符之后自動換行。 如果為假值,則只有空白符會被視為合適的潛在斷行位置,但如果你確實不希望出現分開的單詞則你必須將break_long_words設為假值。 之前版本的默認行為總是允許分開帶有連字符的單詞。

max_lines

  (默認: None) 如果不為None,則輸出內容將最多包含max_lines行,並使placeholder出現在輸出內容的末尾。

  3.4 新版功能.

placeholder

  (默認: [...]') 該文本將在輸出文本被截短時出現在文本末尾。

  3.4 新版功能.

TextWrapper還提供了一些公有方法,類似於模塊層級的便捷函數:

wrap(text)

  對text(字符串) 中的單獨段落自動換行以使每行長度最多為width個字符。 所有自動換行選項均獲取自TextWrapper實例的實例屬性。 返回由輸出行組成的列表,行尾不帶換行符。 如果自動換行輸出結果沒有任何內容,則返回空列表。

fill(text)

  對text中的單獨段落自動換行並返回包含被自動換行段落的單獨字符串。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM