058:インデントを変更する
Python でも正規表現が使用できるので Ruby レシピブックと同じことが可能です。 String#gsub(pattern){|matched| .... } (これは便利)は re.sub の第 2 引数に関数を指定することで代用しています。 String#map {|item| ....} の代用は str.splitlines を核としたジェネレータ式で行いました。しかし、読みやすさという点では、ジェネレータ関数をきっちり定義するほうがよかったかもしれません。
import re
def untabify(s, tabstop=8):
u"""
タブを半角空白文字に
"""
return re.sub(
'(.*?)\t',
lambda mo: (
mo.group(1) +
' ' * (tabstop - (len(mo.group(1)) % tabstop))
),
s)
def tabify(s, tabstop=8):
u"""
半角空白文字をタブに
"""
def repl(mo):
tab, space = divmod(len(untabify(mo.group(0), tabstop)), tabstop)
return '\t' * tab + ' ' * space
return re.sub('(?m)^[ \t]+', repl, s)
def indent0(s, n):
u"""
半角空白文字 n 個分インデントする(タブ非対応)
"""
return re.sub('(?m)^', ' ' * n, s)
def indent(s, n, tabstop=8):
u"""
半角空白文字 n 個分インデントする(タブ対応)
"""
if tabstop:
return ''.join(' ' * n + untabify(line, tabstop)
for line in s.splitlines(True))
else:
return re.sub('(?m)^', ' ' * n, s)
def unindent0(s, n):
u"""
半角空白文字 n 個分アンインデントする(タブ非対応)
"""
return re.sub('(?m)^ {0,%d}' % n, '', s)
def unindent(s, n, tabstop=8):
u"""
半角空白文字 n 個分アンインデントする(タブ対応)
"""
indent_re = re.compile('^ {0,%d}' % n, re.MULTILINE)
if tabstop:
return ''.join(
tabify(
indent_re.sub(
"",
untabify(line, tabstop)),
tabstop)
for line in s.splitlines(True))
else:
return indent_re.sub('', s)