2013-04-17 43 views
9

Tôi đang cố gắng viết một hàm python không sử dụng bất kỳ mô-đun nào sẽ lấy một chuỗi có tab và thay thế các tab bằng dấu cách thích hợp cho kích thước tabstop được nhập. Mặc dù vậy, nó không thể thay thế tất cả các tab size-n bằng n, vì một tab có thể là 1 đến không gian n. Tôi thực sự bối rối, vì vậy nếu bất cứ ai có thể chỉ cho tôi đúng hướng tôi rất cảm kích.Làm cách nào để thay thế các tab tùy chỉnh bằng dấu cách trong một chuỗi, phụ thuộc vào kích thước của tab?

Ví dụ, nếu tabstop là kích thước 4 ban đầu:

123\t123 = 123 123 #one space in between 

nhưng thay đổi để tabstop 5:

123\t123 = 123 123 #two spaces in between 

Tôi nghĩ rằng tôi cần phải pad cuối của chuỗi với không gian cho đến khi chuỗi % n == 0 và sau đó chunk nó, nhưng tôi khá bị mất vào lúc này ..

+0

bạn có muốn "_" cho mỗi tab (\ t) không? – Zangetsu

+1

Sẽ là một ý tưởng hay khi thêm một loạt testcases vào câu hỏi của bạn –

+0

Điều gì sẽ xảy ra nếu khối hóa là 5 và chuỗi dài hơn, ví dụ: 123456 \ t? Kết quả là: 1234_56___? 1234_6____? 123456_? – emigue

Trả lời

2

Vì bạn wan't một hàm python mà không sử dụng bất kỳ thành phần bên ngoài, tôi nghĩ bạn nên thiết kế đầu tiên là thuật toán của hàm của bạn ...

Tôi sẽ đề xuất lặp lại trên mọi char của chuỗi; nếu char i là một tab, bạn cần tính toán bao nhiêu không gian để chèn: chỉ mục "liên kết" tiếp theo là ((i/tabstop) + 1) * tabstop. Vì vậy, bạn cần phải chèn ((i/tabstop) + 1) * tabstop - (i% tabstop). Nhưng một cách dễ dàng hơn là để chèn các tab cho đến khi bạn được liên kết (tức là 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

Cảm ơn mọi người vì đã giúp đỡ. Đây chính xác là những gì tôi đang tìm kiếm Tôi chỉ là có một khối tâm trí cố gắng để quấn tâm trí của tôi xung quanh thuật toán, vì vậy cảm ơn một lần nữa! – Austin

+0

Bất kỳ ai biết cách thay đổi điều này để làm việc với nhiều tab liên tiếp? có vẻ như nó chỉ chọn một trong những đầu tiên – Austin

+0

Trong thử nghiệm tôi chạy nhiều tab là ok: replace_tab ('123 \ t12 \ t1 \ t123456 \ t1234 \ t12345678 \ n') trả về '123.12..1 ... 123456 .. 123412345678 '(với dấu chấm thay thế khoảng trống để dễ đọc) –

2

Xin lỗi, tôi đã đọc sai câu hỏi lần đầu tiên.

Đây là một phiên bản đệ quy mà nên làm việc cho bất kỳ số lượng các tab ở đầu vào:

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

Hãy thử điều này trên các ví dụ – jamylak

1

Mã này có thể giúp bạn:

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

Bạn sẽ cần phải nghiên cứu: định dạng, tách và tham gia chức năng và khái niệm hiểu danh sách.

4

Đối với một chiều dài tab 5:

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

Hoặc: '(5 * '') .join (s.split ('\ t'))' –

1

programm này thay thế tất cả các tab cho các không gian trong một tập tin:

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

tôi cần một cái gì đó tương tự, đây là những gì tôi đã đưa ra:

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

Tôi nghĩ câu trả lời của Remi là đơn giản nhất nhưng có lỗi, nó không giải thích cho trường hợp khi bạn đã ở trên cột "dừng tab". Tom Swirly chỉ ra điều này trong phần bình luận. Dưới đây là một sửa chữa kiểm tra để đề nghị của ông:

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

tôi sử dụng .replace chức năng đó là rất đơn giản:

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

Sử dụng re.sub là đủ.

def untabify(s, tabstop = 4): 
    return re.sub(re.compile(r'\t'), ' '*tabstop, s) 
Các vấn đề liên quan