2013-04-17 14 views
9

Sto provando a scrivere una funzione python che non utilizza alcun modulo che prenderà una stringa che ha schede e sostituirà le schede con spazi appropriati per una dimensione tabstop immessa. Tuttavia, non può sostituire solo tutte le schede size-n di n spazi, dato che una scheda può contenere da 1 a n spazi. Sono davvero confuso, quindi se qualcuno potesse indicarmi la giusta direzione lo apprezzerei molto.Come sostituire le schede personalizzate con spazi in una stringa, dipende dalla dimensione della scheda?

Ad esempio, se tabstop è formato 4 originariamente:

123\t123 = 123 123 #one space in between 

ma cambiato tabstop 5:

123\t123 = 123 123 #two spaces in between 

ritengo devo pad alla fine della stringa con spazi fino stringa % n == 0 e poi tagliarlo, ma al momento sono piuttosto perso ..

+0

si desidera "_" per ogni scheda (\ t)? – Zangetsu

+1

Sarebbe una buona idea aggiungere una serie di test alla tua domanda –

+0

Cosa succede se il blocco è 5 e la stringa è più lunga, ad es. 123456 \ t? Il risultato è: 1234_56___? 1234_6____? 123456_? – emigue

risposta

2

Dal momento che si wan't una funzione Python che non utilizza alcun modulo esterno, penso che si dovrebbe progettare prima l'algoritmo della tua funzione ...

Vorrei proporre di ripetere su ogni carattere della stringa; se char i è una scheda, è necessario calcolare quanti spazi inserire: il successivo indice "allineato" è ((i/tabstop) + 1) * tabstop. Quindi è necessario inserire ((i/tabstop) + 1) * tabstop - (i% tabstop). Ma un modo più semplice è quello di inserire le schede fino a quando siete allineati (vale a dire i% tabstop == 0)

def replace_tab(s, tabstop = 4): 
    result = str() 
    for c in s: 
    if c == '\t': 
     while (len(result) % tabstop != 0): 
     result += ' '; 
    else: 
     result += c  
    return result 
+0

Grazie a tutti per l'aiuto. Questo è esattamente quello che stavo cercando Stavo solo avendo un blocco mentale che cercava di avvolgere la mia mente attorno all'algoritmo, quindi grazie ancora! – Austin

+0

Qualcuno sa come cambiarlo per funzionare con più schede di fila? sembra che riprenda solo il primo – Austin

+0

Nel test che ho eseguito più schede erano ok: replace_tab ('123 \ t12 \ t1 \ t123456 \ t1234 \ t12345678 \ n') restituisce '123.12..1 ... 123456 .. 123412345678 '(con punti che sostituiscono gli spazi per la leggibilità) –

2

Spiacente, ho letto male la domanda la prima volta.

Questa è una versione ricorsiva che dovrebbe funzionare per qualsiasi numero di schede in ingresso:

def tabstop (s , tabnum = 4): 
    if not '\t' in s: 
     return s 
    l = s.find('\t') 
    return s[0:l]+' '*(tabnum-l)+tabstop(s[l+1:],tabnum) 
+0

Prova questo sugli esempi – jamylak

1

Questo codice può aiutare a:

initial_string = "My \tstring \ttest\t" 
block_size = "5" 
"".join([("{block_value:"+str(block_size)+"s}").format(block_value=block) 
    for block in initial_string.split("\t")]) 

Avrete bisogno di studiare: formato, diviso e unire la funzione e il concetto di comprensione dell'elenco.

4

Per una lunghezza scheda 5:

>>> s = "123\t123" 
>>> print ''.join('%-5s' % item for item in s.split('\t')) 
123 123 
>>> 
+2

Oppure: '(5 * '') .join (s.split ('\ t'))' –

1

Questo programma sostituisce tutte le schede per gli spazi in un file:

def tab_to_space (line, tab_lenght = 8): 
    """this function change all the tabs ('\\t') for spaces in a string, 
     the lenght of the tabs is 8 by default""" 

    while '\t' in line: 
     first_tab_init_pos = line.find('\t') 
     first_tab_end_pos = (((first_tab_init_pos // tab_lenght)+1) * tab_lenght) 
     diff = first_tab_end_pos - first_tab_init_pos 
     if diff == 0: 
      spaces_string = ' ' * tab_lenght 
     else: 
      spaces_string = ' ' * diff 
     line = line.replace('\t', spaces_string, 1) 
    return line 


inputfile = open('inputfile.txt', 'r') 
outputfile = open('outputfile.txt', 'w') 
for line in inputfile: 
    line = tab_to_space(line) 
    outputfile.write(line) 
inputfile.close() 
outputfile.close() 
0

avevo bisogno di qualcosa di simile, ecco cosa mi si avvicinò con:

import re 

def translate_tabs(tabstop = 8): 
    offset = [0] 
    def replace(match, offset=offset): 
    offset[0] += match.start(0) 
    return " " * (tabstop - offset[0] % tabstop) 
    return replace 

re.sub(r'\t', translate_tabs(4), "123\t123") 
# => '123 123' 

re.sub(r'\t', translate_tabs(5), "123\t123") 
# => '123 123' 
0

Penso che la risposta di Remi sia la più semplice ma ha un bug, non tiene conto del caso quando si è già su una colonna "tab stop". Tom Swirly lo ha sottolineato nei commenti. Ecco una correzione testato per il suo suggerimento:

def replace_tab(s, tabstop = 4): 
    result = str() 

    for c in s: 
     if c == '\t': 
      result += ' ' 
      while ((len(result) % tabstop) != 0): 
       result += ' ' 
     else: 
      result += c  

    return result 
3

Io uso .Rimontare funzione che è molto semplice:

line = line.replace('\t', ' ') 
0

Utilizzare il re.sub è sufficiente.

def untabify(s, tabstop = 4): 
    return re.sub(re.compile(r'\t'), ' '*tabstop, s)