2007-06-19
Python Cookbook 1.15 控制和转换Tab字符
需求:
需要将字符串中指定数量的空格和Tab相互转换.
讨论:
空格和Tab的相互转换在文本处理中是很常见的需求,在Python中,可以方便的使用expandtabs方法来实现这个需求.因为字符串是不可以修改的,所以该方法返回了源字符串的一个副本.当然 ,我们可以将源字符串的名称绑定到修改后的字符串上.显然两个对象是不同的,如:
mystring = 'hello\tworld'
old = mystring
mystring = mystring.expandtabs()
print id(old)
print id(mystring)
>>> 30896000
30896048
这样并不改变源字符串所指向的对象,而是mystring指向了新构造的字符串.默认的情况下,expandtabs使用8个空格替换Tab,你可以传递希望的数字做为expandtabs的参数:
把空格转换为Tab是比较少见的需求,所以在Python中,并没有提供这样的方法.我们可以自己来写代码完成这个需求 ,在Python中,使用"分割/处理/合并"这样的流程处理和转换字符串是最有效的.
def unexpand(astring, tablen=8):
import re
# split into alternating space and non-space sequences
pieces = re.split(r'( +)', astring.expandtabs(tablen))
# keep track of the total length of the string so far
lensofar = 0
for i, piece in enumerate(pieces):
thislen = len(piece)
lensofar += thislen
if piece.isspace( ):
# change each space sequences into tabs+spaces
numblanks = lensofar % tablen
numtabs = (thislen-numblanks+tablen-1)/tablen
pieces[i] = '\t'*numtabs + ' '*numblanks
return ''.join(pieces)
这里写的方法只适用于当行字符串,如果多行字符串,请使用
' '.join([ unexpand(s) for s in astring.splitlines(True) ]).
上面的方法使用正则式来处理字符串,在很多语言中, 正则式都是处理字符串的利器.在上面的方法中,使用re的split方法来完成需求,它返回了一个序列,里面是用原先用空白字符分隔的字符串和空白字符.接下来,我们对每一个空白字符进行处理,尽可能多的把它们替换成Tab.
在编程中可能遇到另外的需求,比如处理行首的缩进.在Python中,需要检查源码中的缩进是否一致,是否有空格和Tab混用的情况,然后可以把它们统一换成空格.使用上面的方法会遇到一个问题,就是也会替换行中的Tab或空格,而这也许不是想要的结果,遇到这样的情况,我们需要修改一下正则式:
def expand_at_linestart(P, tablen=8):
import re
def exp(mo):
return mo.group( ).expand(tablen)
return ''.join([ re.sub(r'^\s+', exp, s) for s in P.splitlines(True) ])
上面的方法利用了re的sub方法,它在处理字符串时,每遇到一个匹配项,会调用参数中的方法来处理,可以看出,上面的方法是针对多行字符串来写的,当然,它也同样适用与单行字符串.
相关说明:
re.split(pattern, string, maxsplit=0)
Split the source string by the occurrences of the pattern,
returning a list containing the resulting substrings.
re.sub(pattern, repl, string, count=0)
Return the string obtained by replacing the leftmost
non-overlapping occurrences of the pattern in string by the
replacement repl. repl can be either a string or a callable;
if a callable, it's passed the match object and must return
a replacement string to be used.
需要将字符串中指定数量的空格和Tab相互转换.
讨论:
空格和Tab的相互转换在文本处理中是很常见的需求,在Python中,可以方便的使用expandtabs方法来实现这个需求.因为字符串是不可以修改的,所以该方法返回了源字符串的一个副本.当然 ,我们可以将源字符串的名称绑定到修改后的字符串上.显然两个对象是不同的,如:
mystring = 'hello\tworld'
old = mystring
mystring = mystring.expandtabs()
print id(old)
print id(mystring)
>>> 30896000
30896048
这样并不改变源字符串所指向的对象,而是mystring指向了新构造的字符串.默认的情况下,expandtabs使用8个空格替换Tab,你可以传递希望的数字做为expandtabs的参数:
把空格转换为Tab是比较少见的需求,所以在Python中,并没有提供这样的方法.我们可以自己来写代码完成这个需求 ,在Python中,使用"分割/处理/合并"这样的流程处理和转换字符串是最有效的.
def unexpand(astring, tablen=8):
import re
# split into alternating space and non-space sequences
pieces = re.split(r'( +)', astring.expandtabs(tablen))
# keep track of the total length of the string so far
lensofar = 0
for i, piece in enumerate(pieces):
thislen = len(piece)
lensofar += thislen
if piece.isspace( ):
# change each space sequences into tabs+spaces
numblanks = lensofar % tablen
numtabs = (thislen-numblanks+tablen-1)/tablen
pieces[i] = '\t'*numtabs + ' '*numblanks
return ''.join(pieces)
这里写的方法只适用于当行字符串,如果多行字符串,请使用
' '.join([ unexpand(s) for s in astring.splitlines(True) ]).
上面的方法使用正则式来处理字符串,在很多语言中, 正则式都是处理字符串的利器.在上面的方法中,使用re的split方法来完成需求,它返回了一个序列,里面是用原先用空白字符分隔的字符串和空白字符.接下来,我们对每一个空白字符进行处理,尽可能多的把它们替换成Tab.
在编程中可能遇到另外的需求,比如处理行首的缩进.在Python中,需要检查源码中的缩进是否一致,是否有空格和Tab混用的情况,然后可以把它们统一换成空格.使用上面的方法会遇到一个问题,就是也会替换行中的Tab或空格,而这也许不是想要的结果,遇到这样的情况,我们需要修改一下正则式:
def expand_at_linestart(P, tablen=8):
import re
def exp(mo):
return mo.group( ).expand(tablen)
return ''.join([ re.sub(r'^\s+', exp, s) for s in P.splitlines(True) ])
上面的方法利用了re的sub方法,它在处理字符串时,每遇到一个匹配项,会调用参数中的方法来处理,可以看出,上面的方法是针对多行字符串来写的,当然,它也同样适用与单行字符串.
相关说明:
re.split(pattern, string, maxsplit=0)
Split the source string by the occurrences of the pattern,
returning a list containing the resulting substrings.
re.sub(pattern, repl, string, count=0)
Return the string obtained by replacing the leftmost
non-overlapping occurrences of the pattern in string by the
replacement repl. repl can be either a string or a callable;
if a callable, it's passed the match object and must return
a replacement string to be used.
标签: Python