# of course, in Python, we do have a built-in tab expansion string method:
# method .expandtabs(tablen=8) of string objects! If we *didn't* have
# it, though, here's how we might make it ourselves...:
# string processing tends to be faster in a split/process/rejoin
# approach than by repeated overall-string transformations, so...:
def expand_with_re(astring, tablen=8):
import re
pieces = re.split(r'(\t)', astring)
lensofar = 0
for i in range(len(pieces)):
if pieces[i]=='\t':
pieces[i] = ' '*(tablen-lensofar%tablen)
lensofar += len(pieces[i])
return ''.join(pieces)
# note we used re.split, rather than plain string splitting, because
# re.split with a '(group)' in the re gives us the splitters too,
# which is quite handy here for us to massage the pieces list into
# our desired form for the final ''.join. However, '\t'.split,
# "interleaving" the blank joiners, looks a bit better still:
def expand(astring, tablen=8):
result = []
for piece in astring.split('\t'):
result.append(piece)
result.append(' '*(tablen-len(piece)%tablen))
return ''.join(result[:-1])
# for the 'unexpanding', though, the "joiners" (spaces) are
# really crucial, so let's go back to the re approach (and
# _here_ we don't have a built-in method of strings...!):
def unexpand(astring, tablen=8):
import re
pieces = re.split(r'( +)', astring)
lensofar = 0
for i in range(len(pieces)):
thislen = len(pieces[i])
if pieces[i][0]==' ':
numblanks = (lensofar+thislen)%8
numtabs = (thislen-numblanks+7)/8
pieces[i] = '\t'*numtabs + ' '*numblanks
lensofar += thislen
return ''.join(pieces)