文章来自《Python cookbook》.

翻译仅仅是为了个人学习,其它商业版权纠纷与此无关!

-- 0.706 [2004-09-19 18:08:39]

1. Expanding and Compressing Tabs 扩展以及压缩制表符(Tab)

Credit: Alex Martelli

1.1. 问题 Problem

You want to convert tabs in a string to the appropriate number of spaces, or vice versa.

你想将字符串中的制表符(tab)转换为适当数量的空格(space),或相反.

1.2. 解决 Solution

Changing tabs to the appropriate number of spaces is a reasonably frequent task, easily accomplished with Python strings' built-in expandtabs method. Because strings are immutable, the method returns a new string object (a modified copy of the original one). However, it's easy to rebind a string variable name from the original to the modified-copy value:

改变制表符(tab)为适当数量的空格(space)是一个相当频繁的工作,它可以很容易地用Python 字符串的内建方法expandtabs来完成.因为字符串是不可变的,该方法返回一个新的字符串对象(原字符串对象的一个修改后的拷贝).可是,可以简单地将一个字符串变量名从原来的值重新绑定到新的值上:

   1 mystring = mystring.expandtabs(  )

This doesn't change the string object to which mystring originally referred, but it does rebind the name mystring to a newly created string object in which tabs are expanded into runs of spaces.

这确实没有改变mystring原先引用的字符串对象,但实际上它重新绑定名字mystring到了一个新的字符串对象上,其中的制表符(tab)被扩展为8个空格(runs=8? ,按python manual,被扩展为8个空格--译注).

Changing spaces into tabs is a rare and peculiar need. Compression, if that's what you're after, is far better performed in other ways, so Python doesn't offer a built-in way to unexpand spaces into tabs. We can, of course, write one. String processing tends to be fastest in a split/process/rejoin approach, rather than with repeated overall string transformations:

改变空格(space)为制表符(tab)是一个的特殊且罕见的需要。压缩空间,如果那真是你要做的,那么用其它方法完成要好得多,因此python中没有提供内建方法来 unexpand 空格(space)为制表符(tab)。当然,我们能自己写一个。在字符串处理中,split/process/rejoin往往是最快的方式,尤其是与重复地处理整个的字符串转换相比:

   1 def unexpand(astring, tablen=8):
   2     import re
   3     pieces = re.split(r'( +)', astring.expandtabs(tablen))
   4     lensofar = 0
   5     for i in range(len(pieces)):
   6         thislen = len(pieces[i])
   7         lensofar += thislen
   8         if pieces[i][0]==' ':
   9             numblanks = lensofar % tablen
  10             numtabs = (thislen-numblanks+tablen-1)/tablen
  11             pieces[i] = '\t'*numtabs + ' '*numblanks
  12     return ''.join(pieces)

1.3. 讨论 Discussion

If expandtabs didn't exist, we could write it up as a function. Here is a regular expression-based approach, similar to the one used in the recipe's unexpand function:

如果expandtabs不存在,我们可以写出一个函数来实现。这里是一个使用规则表达式的方法,与在配方中unexpand函数使用的方法类似:

#!python
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)

When the regular expression contains a (parenthesized) group, re.split gives us the splitters too. This is useful here for massaging the pieces list into the form we want for the final ' '.join. However, a string split by '\t', followed by interleaving the spaces joiners of suitable lengths, looks a bit better in this case:

当规则表达式中包含(...)子组时,re.split同时会给出分隔串。这对最后使用 ' '.join ,把这里的pieces列表整理成我们想要的格式是很有用的。可是在这种情况下,一个被'\t'分隔的字符串,后面交错地跟着适当长度的空格,看起来要稍好一点:

   1 def expand(astring, tablen=8):
   2     result = []
   3     for piece in astring.split('\t'):
   4         result.append(piece)
   5         result.append(' '*(tablen-len(piece)%tablen))
   6     return ''.join(result[:-1])

1.4. 参考 See Also

Documentation for the expandtabs function in the string module in the Library Reference; Perl Cookbook Recipe 1.7.