2012-06-22 14 views
32

Dire che ho la stringaPython ha una funzione incorporata per estrarre una stringa multilinea?

s = """ 
    Controller = require 'controller' 

    class foo 
     view: 'baz' 
     class: 'bar' 

     constructor: -> 
      Controller.mix @ 
""" 

Ogni linea nella stringa ha ora una globale 4 spazio indentazione. Se questa stringa è stata dichiarata all'interno di una funzione, avrà una rientranza globale di 8 spazi, ecc.

Python ha una funzione per rimuovere il rientro globale a sinistra della stringa?

Vorrei che la produzione la funzione di essere:

Controller = require 'controller' 

class foo 
    view: 'baz' 
    class: 'bar' 

    constructor: -> 
     Controller.mix @" 

risposta

61

non una funzione built-in, ma una funzione della libreria standard: textwrap.dedent()

>>> print(textwrap.dedent(s)) 

Controller = require 'controller' 

class foo 
    view: 'baz' 
    class: 'bar' 

    constructor: -> 
     Controller.mix @ 
+0

Non sapevo che esistesse. Roba utile +1. –

+0

Questo è l'accumulo più rapido di voti positivi che abbia mai visto per una risposta – Hubro

+1

Codice sorgente della deduzione qui: http://hg.python.org/cpython/file/2.7/Lib/textwrap.py – Jiri

5

textwrap.dedent() è vicino a ciò che si vuole , ma non implementa ciò che hai chiesto, perché ha una nuova linea guida. È possibile avvolgere dedent in una funzione che mette a nudo la nuova linea che conduce da s:

def my_dedent(string): 
    if string and string[0] == '\n': 
     string = string[1:] 
    return textwrap.dedent(string) 

Tuttavia textwrap.dedent() gestisce le linee con solo spazi in modo speciale che è OK se si sta generando sorgente Python da una dichiarazione multilinea trattino, in cui trailing lo spazio bianco è insignificante.

Ma in generale non è opportuno che textwrap.dedent() rimuove gli spazi extra da linee con più spazi vuoti rispetto alla 'massima trattino', rimuove gli spazi bianchi da tutte le linee di spazi bianchi e che descards qualsiasi spazio bianco prima della chiusura """, soprattutto perché questo comportamento è undocumented and done with non-transparent regular expressions .

Poiché anch'io genera codice sorgente non Python in cui gli spazi sono spesso significativi, utilizzo la seguente routine. Non gestisce il rientro TAB, ma fornisce l'output richiesto senza il comando newline, dove textwrap.dedent() non riesce.

def remove_leading_spaces(s, strict=False): 
    '''Remove the maximum common spaces from all non-empty lines in string 

Typically used to remove leading spaces from all non-empty lines in a 
multiline string, preserving all extra spaces. 
A leading newline (when not useing '"""\') is removed unless the strict 
argument is True. 

Note that if you want two spaces on the last line of the return value 
without a newline, you have to use the max indentation + 2 spaces before 
the closing """. If you just input 2 spaces that is likely to be the 
maximum indent. 
    ''' 
    if s and not strict and s[0] == '\n': 
     s = s[1:] 
    lines = s.splitlines(True) # keep ends 
    max_spaces = -1 
    for line in lines: 
     if line != '\n': 
      for idx, c in enumerate(line[:max_spaces]): 
       if not c == ' ': 
        break 
      max_spaces = idx + 1 
    return ''.join([l if l == '\n' else l[max_spaces-1:] for l in lines]) 
+0

OP non ha chiesto informazioni nuova linea di comando o rimozione della stessa. La cura più semplice per leader di newline è semplicemente il backslash dopo aver portato la citazione tripla. (Come già sottolineato da @firegurafiku). Ci possono essere dei motivi per sostituire textwrap.dedent() con una funzione personalizzata, ma la rimozione di newline, che può essere semplicemente evitata con il backslash, non sembra buona. – gwideman

+0

La rimozione ** programmatic ** della newline iniziale è necessaria per ottenere dagli input forniti dall'OP alla richiesta richiesta. s modi diversi per gestirlo, come riscrivere la stringa su una riga con backslash espliciti. Ma l'OP non ha chiesto come modificare il suo input come sembra suggerire. – Anthon

+0

Sembra che il compito dell'OP non sia quello di elaborare le stringhe in generale, è come scrivere una stringa letterale multilinea con la sua origine rientrata per corrispondere all'indentazione di origine circostante, ma non avere la stringa risultante che contiene tale indentazione.La domanda specifica dell'OP era "Python ha una funzione per rimuovere il rientro sinistro globale della stringa?". Il principale problema di nuova riga è pertinente, ma non è necessario che venga eliminato dalla funzione richiesta. Detto questo, le tue note sulla deduzione della rimozione di spazi bianchi extra in alcune situazioni sono un po 'allarmanti e sarebbe interessante sapere di più. – gwideman

Problemi correlati