2013-04-17 33 views
9

Próbuję napisać funkcję Pythona, nie używając żadnych modułów, które wezmą ciąg znaków z zakładkami i zastąpią tabulatory spacjami odpowiednimi dla wprowadzonego rozmiaru tabulatury. Nie można jednak po prostu zastąpić wszystkich kart o wielkości n za pomocą n spacji, ponieważ zakładka może mieć od 1 do n spacji. Jestem bardzo zdezorientowany, więc jeśli ktoś mógłby wskazać mi właściwy kierunek, byłbym bardzo wdzięczny.Jak zamienić niestandardowe karty spacjami w ciągu znaków, zależy od wielkości karty?

Na przykład jeśli tabulator ma rozmiar 4 pierwotnie:

123\t123 = 123 123 #one space in between 

ale zmienił się TabStop 5:

123\t123 = 123 123 #two spaces in between 

Chyba muszę pad koniec sznurka ze spacjami do STRING % n == 0, a następnie poróżnij go, ale jestem całkiem zagubiony w tej chwili ..

+0

Czy chcesz "_" dla każdej zakładki (\ t)? – Zangetsu

+1

Dobrze byłoby dodać kilka pytań testowych do pytania: –

+0

Co się stanie, jeśli rozmiar bloku wynosi 5, a ciąg jest dłuższy, np. 123456 \ t? Wynik jest: 1234_56___? 1234_6____? 123456_? – emigue

Odpowiedz

2

Ponieważ wa funkcję Pythona, który nie korzysta z żadnego modułu zewnętrznego, myślę, że należy zaprojektować najpierw algorytm twojej funkcji ...

Proponuję iterować na każdym znaku sznurka; jeśli char i jest zakładką, musisz obliczyć ile spacji ma zostać wstawionych: następny "wyrównany" indeks to ((i/tabstop) + 1) * tabstop. Musisz więc wstawić ((i/tabstop) + 1) * tabstop - (i% tabstop). Ale jest łatwiejszy sposób, aby wstawić zakładki, dopóki nie są wyrównane (tzn ja% 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

Dziękuję wszystkim za pomoc. Właśnie tego szukałem, po prostu miałem mentalną blokadę, próbując zawinąć mój umysł wokół algorytmu, więc jeszcze raz dziękuję! – Austin

+0

Ktoś wie, jak to zmienić, aby działało z wieloma zakładkami z rzędu? wygląda na to, że tylko podnosi pierwszą. – Austin

+0

W teście, w którym działałem, wiele zakładek było ok: replace_tab ('123 \ t12 \ t1 \ t123456 \ t1234 \ t12345678 \ n') zwraca '123.12..1 ... 123456 .. 123412345678 '(z kropkami zastępującymi spacje dla czytelności) –

2

Przepraszam, błędnie przeczytałem pytanie po raz pierwszy.

To jest wersja rekurencyjna, które powinny pracować dla dowolnej liczby kart na wejściu:

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

Wypróbuj na przykładach – jamylak

1

Ten kod może pomóc:

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")]) 

Trzeba studiować: format podzielonego i dołącz do koncepcji funkcji i listy.

4

Dla długości zakładki 5:

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

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

1

Ten programowe zastępuje wszystkie zaczepy dla przestrzeni w pliku:

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

potrzebowałem czegoś podobnego, oto co wymyśliłem:

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

Myślę, że odpowiedź Remi jest najprostsza, ale ma błąd, nie uwzględnia przypadku, gdy jesteś już w kolumnie "tabulator". Tom Swirly wskazał to w komentarzach. Oto sprawdzone fix do jego sugestii:

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

używam .replace funkcję, która jest bardzo prosta:

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

Użyj re.sub wystarczy.

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