2013-04-17 5 views
9

Я пытаюсь написать функцию python, не используя какие-либо модули, которые берут строку с вкладками и заменяют вкладки пробелами, соответствующими введенному размеру табуста. Он не может просто заменить все вкладки размера-n на n пробелов, поскольку вкладка может иметь от 1 до n пробелов. Я действительно смущен, поэтому, если бы кто-нибудь мог просто указать мне в правильном направлении, я бы очень признателен.Как заменить пользовательские вкладки пробелами в строке, зависит от размера вкладки?

Например, если значение отступа размер 4 первоначально:

123\t123 = 123 123 #one space in between 

но изменен TabStop 5:

123\t123 = 123 123 #two spaces in between 

Я думаю, что нужно раздуть конец строки с пробелами, пока строки % n == 0, а затем купите его, но в настоящий момент я довольно утерян.

+0

Вы хотите «_» для каждой вкладки (\ t)? – Zangetsu

+1

Было бы неплохо добавить кучу тестовых ящиков на ваш вопрос –

+0

Что произойдет, если размер блока равен 5, а строка более длинная, например. 123456 \ t? Результат: 1234_56___? 1234_6____? 123456_? – emigue

ответ

2

Поскольку вы wan't функцию питона, который не использует какой-либо внешний модуль, я думаю, вы должны разработать сначала алгоритм вашей функции ...

Я бы предложил итерацию на каждом символе строки; если char i является вкладкой, вам нужно вычислить, сколько пробелов нужно вставить: следующий «выровненный» индекс равен ((i/tabstop) + 1) * tabstop. Поэтому вам нужно вставить ((i/tabstop) + 1) * tabstop - (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

Спасибо всем за помощь. Это именно то, что я искал, у меня был только ментальный блок, который пытался обмануть алгоритм, так что еще раз спасибо! – Austin

+0

Кто-нибудь знает, как изменить это, чтобы работать с несколькими вкладками в строке? кажется, что он только подбирает первый – Austin

+0

В тесте я запустил несколько вкладок в порядке: replace_tab ('123 \ t12 \ t1 \ t123456 \ t1234 \ t12345678 \ n') возвращает '123.12..1 ... 123456 .. 123412345678 '(с точками, заменяющими пробелы для удобочитаемости) –

2

Извините, я неправильно прочитал вопрос в первый раз.

Это рекурсивная версия, которая должна работать для любого количества вкладок на входе:

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

Попробуйте это на примерах – jamylak

1

Этот код может помочь вам:

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

Вам нужно будет изучить: формат, сплит и присоединиться к функции и концепции понимания списка.

4

При длине закладки 5:

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

Или: '(5 * '') .join (s.split ('\ t'))' –

1

Эта программа заменяет все вкладки пространства в файле:

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

мне нужно было что-то подобное, вот что я придумал:

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

Я думаю, что ответ Реми самый простой, но он имеет ошибку, он не учитывает случай, когда вы уже в столбце «tab stop». Том Свинли указал на это в комментариях. Вот испытанный исправление к его предложению:

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

Я использую .Привернуть функцию, которая очень проста:

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

Используйте re.sub достаточно.

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