在我的文字中,我想用两个空格替换所有前导标签,但只保留非前导标签。
例如:
a
\tb
\t\tc
\td\te
f\t\tg
("a\n\tb\n\t\tc\n\td\te\nf\t\tg"
)
应该变成:
a
b
c
d\te
f\t\tg
("a\n b\n c\n d\te\nf\t\tg"
)
对于我的情况,我可以通过多次替换操作来执行此操作,重复与许多最大嵌套级别一样多次,或者直到没有任何更改。
但是一次运行也不可能吗?
我尝试了但是没有设法提出一些东西,我提出的最好的东西是外观:
re.sub(r'(^|(?<=\t))\t', ' ', a, flags=re.MULTILINE)
哪个“仅”进行了错误的替换(f
和g
之间的第二个标签)。
现在可能在单次运行中根本无法进行正则表达式,因为已经更换的部件无法再次匹配(或者更换不会立即发生)并且您无法排序“计算“在正则表达式中,在这种情况下,我希望看到一些更详细的解释为什么(只要这不会转移到[cs.se]领域)。
我目前正在使用Python,但这几乎适用于任何类似的正则表达式实现。
答案 0 :(得分:8)
您可以匹配行开头的标签,并使用re.sub
内的lambda替换为双倍空格乘以匹配的长度:
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 :(得分:1)
也可以在没有正则表达式的情况下使用replace()
在单行中执行此操作:
>>> 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'
答案 2 :(得分:1)
这有点疯狂,但它有效:
"\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() ])