2016-08-19 4 views
4

私のテキストでは、先行するすべてのタブを2つのスペースに置き換えます。例えば1つの置換操作を使用すると、先行するすべてのタブを空白に置き換えます。

:私は、複数の置換操作でそれを行うことができ、私のケースでは

a 
    b 
    c 
    d\te 
f\t\tg 

"a\n b\n c\n d\te\nf\t\tg"

a 
\tb 
\t\tc 
\td\te 
f\t\tg 

"a\n\tb\n\t\tc\n\td\te\nf\t\tg"

がに変わるはずです、多くの回数繰り返すネスティングレベルまたは何も変更されなくなるまで

しかし、1回の実行でも実行できないでしょうか?

私が試みたが、何かを思い付くことが出来なかった私はまだ思いついた最高のは、前後参照していました:「のみ」fgの間に1つの誤った交換(2番目のタブを作る

re.sub(r'(^|(?<=\t))\t', ' ', a, flags=re.MULTILINE) 

)。

すでに置き換えられた部分を再度マッチングできない(または置き換えがすぐには起こらない)ため、一回の実行で正規表現で行うのは不可能なことがあります。正規表現で "数えて"、この場合、なぜ(これがあまりにも多くの[cs.se]領域にシフトしない限り)何らかの詳細な説明を参照したいと思います。

私は現在Pythonで作業していますが、これはほぼ同様の正規表現の実装にも当てはまります。

+1

各行に '.strip()'を付けてみませんか? – jonrsharpe

+0

@jonrsharpe: '\ t'sを取り除きません。 – phk

答えて

8

あなたは、行の先頭にあるタブに合わせて、試合の長さを乗じたダブルスペースで置き換えることre.sub内のラムダを使用することがあります。

import re 
s = "a\n\tb\n\t\tc\n\td\te\nf\t\tg"; 
print(re.sub(r"^\t+", lambda m: " "*len(m.group()), s, flags=re.M)) 

Python demo

1

を参照してください。ここ

>>> s = "a\n\tb\n\t\tc\n\td\te\nf\t\tg" 
>>> "\n".join(x.replace("\t"," ",len(x)-len(x.lstrip("\t"))) for x in s.split("\n")) 
'a\n b\n c\n d\te\nf\t\tg' 
1

これをちょっとCRAである:1つのライナーでreplace()を使って正規表現せずにこれを行うことも可能ですzyが動作しますが、それは動作します:

"\n".join([ re.sub(r"^(\t+)"," "*(2*len(re.sub(r"^(\t+).*","\1",x))),x) for x in "a\n\tb\n\t\tc\n\td\te\nf\t\tg".splitlines() ]) 
関連する問題