如何根据选项卡的大小用字符串中的空格替换自定义选项卡?

问题描述 投票:0回答:14

我正在尝试编写一个不使用任何模块的Python函数,该函数将采用带有制表符的字符串,并将制表符替换为适合输入制表位大小的空格。但它不能仅用 n 个空格替换所有大小为 n 的制表符,因为制表符可能是 1 到 n 个空格。我真的很困惑,所以如果有人能指出我正确的方向,我将不胜感激。

例如, 如果制表位最初尺寸为 4:

123\t123 = 123 123 #one space in between

但改为制表符 5:

123\t123 = 123  123 #two spaces in between

我想我需要用空格填充字符串的末尾,直到 string%n==0 然后将其分块,但我现在很迷茫..

python whitespace spaces tabstop
14个回答
5
投票

对于 5 的制表符长度:

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

4
投票

既然你不想要一个不使用任何外部模块的Python函数,我认为你应该首先设计你的函数的算法......

我建议迭代字符串的每个字符;如果 char i 是制表符,则需要计算要插入多少个空格:下一个“对齐”索引是 ((i / tabstop) + 1) * tabstop。所以你需要插入 ((i / tabstop) + 1) * tabstop - (i % 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

4
投票

我使用 .replace 函数,非常简单:

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

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)

2
投票

我认为雷米的答案是最简单的,但它有一个错误,它没有考虑到当你已经在“制表位”列时的情况。 Tom Swirly 在评论中指出了这一点。这是针对他的建议的经过测试的修复:

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

2
投票

这是最简单的方法

def replaceTab(text,tabs)
    return text.replace('\t', ' ' * tabs)

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

您需要学习:格式、拆分和连接函数以及列表理解概念。


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()

1
投票

如果您有需要添加 n 个空格而不是自定义制表符的需求 你可以简单地写下面的代码。我已经展示了使用两个函数的实现,每个函数都有不同的解决方法。您可以使用任何函数!

例如。让字符串位于变量“code”中,“x”为制表符的大小

code = "def add(x, y)\f\treturn x + y"
x=4

def convertTabs(code, x):
    temp=""
    for i in range(0,x):
        temp+=" "
    return code.replace("\t",temp) 

def converTabs1(code,x):
    return code.replace("\t",x*" ")

上面的两个函数都会给出相同的值,但第二个函数超级棒!


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
投票

使用re.sub就够了。

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

0
投票

修复@rémi 的答案 此实现尊重前导选项卡和任何连续选项卡

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

0
投票
def expand_tabs(text: str, width: int = 8) -> str:
    """
    Expand each tab to one or more spaces
    """
    assert width > 0
    while (i := text.find('\t')) >= 0:
        text = text[:i] + ' ' * (width - i % width) + text[i+1:]
    return text

0
投票

只是为了完整起见,因为下面的内容不适合对 kzah 的 ksar 用户的答案进行评论,他想出了一个非常有趣的方法,但它不是正确的吗:

offsetAddon = 0
def spaces(tabSize=8):
  def replace(match):
    global offsetAddon
    spaceMultipl = (tabSize - (match.start(0) + offsetAddon) % tabSize)
    offsetAddon += (spaceMultipl - 1)
    return " " * spaceMultipl    
  return replace
tab=r'\t'
s="\t1\t12\t123\t1234\t12345\t123456\t1234567\t12345678\t12\t"
print(f'''"{re.sub(tab, spaces(4), s)}"''') # gives:  
# "    1   12  123 1234    12345   123456  1234567 12345678    12  "
© www.soinside.com 2019 - 2024. All rights reserved.