这个问题与this question几乎完全相同,只是我必须转到三个空格(公司编码指南)而不是四个,并且接受的解决方案只会使匹配的模式加倍。这是我的第一次尝试:
:%s/^\(\s\s\)\+/\1 /gc
但这不起作用,因为四个空格被三个替换。所以我认为我需要的是一些方法来计算模式匹配“+”的次数,并使用该数字来创建替换的另一面但我觉得这个功能可能在Vim的正则表达式中不可用(让如果你认为可能的话,我知道。)
我还尝试通过首先替换最大的缩进然后再替换下一个较小的缩进来手动进行替换,直到我将其全部转换为但是这很难跟踪空格:
:%s/^ \(\S\)/ \1/gc
我可以通过Perl发送它,因为看起来Perl可能有能力使用它的Extended Patterns。但我无法使用我的Perl版本。这是我试图计算一个的尝试:
:%!perl -pe 'm<(?{ $cnt = 0 })(a(?{ local $cnt = $cnt + 1; }))*aaaa(?{ $res = $cnt })>x; print $res'
我的最后一招是编写一个Perl脚本来进行转换,但我希望在Vim中有一个更通用的解决方案,以便我可以重用这个想法来解决未来的其他问题。
答案 0 :(得分:8)
让vim为你做这件事吗?
:set sw=3<CR>
gg=G
第一个命令设置shiftwidth
选项,即你缩进的数量。第二行说:转到文件顶部(gg
),然后重新加载(=
)直到文件末尾(G
)。
当然,这取决于vim对于您正在使用的语言具有良好的格式化程序。如果没有,可能会有些事情搞砸了。
Regexp方式......更安全,但不太可理解:
:%s#^\(\s\s\)\+#\=repeat(' ',strlen(submatch(0))*3/2)#g
(我必须做一些实验。)
两点:
\=
开头,则将其评估为表达式。/
,因此/
可用于分割。答案 1 :(得分:1)
你要求的perl版本......
从命令行(就地编辑,无备份):
bash$ perl -pi -e 's{^((?: )+)}{" " x (length($1)/2)}e' YOUR_FILE
(就地,原始备份到“YOUR_FILE.bak”):
bash$ perl -pi.bak -e 's{^((?: )+)}{" " x (length($1)/2)}e' YOUR_FILE
编辑YOUR_FILE时来自vim:
:%!perl -pe 's{^((?: )+)}{" " x (length($1)/2)}e'
正则表达式匹配行的开头,后跟(捕获的一组)一个或多个“两个空格”组。替换模式是perl表达式(因此是'e'修饰符),它计算捕获的“两个空间”组的数量,并创建相同数量的“三个空间”组的字符串。如果原件中存在“额外”空间,则在替换后保留。因此,如果你之前有三个空格,那么你将有四个空格,五个之前将变成七个空格,等等。