vim中的子匹配替换分支

时间:2012-05-23 21:01:29

标签: regex vim

我想使用多个分支进行搜索,并从匹配分支中获取子匹配以用于替换。

对于这个特定的问题,我想抓住任何完全由'='或' - '(较小的子集)中的一个字符组成的行,其中至少有3个字符,每个字符的空格条件不同。< / p>

所以我使用下面的表达式来匹配它们:

^\t\(=\)\{3,}\_$\|[ ]\{5,}^\(-\)\{3,}\_$

接下来我要做的是在替换中使用子匹配。我以为我可以这样做:

:.s/^\t\(=\)\{3,}\_$\|[ ]\{5,}^\(-\)\{3,}\_$/apple\1banana/e

但是,如果第一个分支(带有'=')匹配,而不是第二个分支,它似乎才有效。我怎样才能做到这一点?我正在寻找一个解决方案,让我可以使用20个分支,并且仍然能够从匹配的分支中获得子匹配。

2 个答案:

答案 0 :(得分:2)

从我看来,你不需要小组。这似乎和你的命令一样(我没有要测试的样本):

:.s/^\t\zs=\ze=\{2,}$\|^[ ]\{5,}\zs-\ze-\{2,}$/apple&banana/e

这将把所有[ - =]放在替换中:

:.s/^\t\zs=\{3,}$\|^[ ]\{5,}\zs-\{3,}$/apple&banana/e

如果您可以共享需要编辑的文本样本和预期结果,那么可以更轻松地测试我写的内容是否有效。

答案 1 :(得分:1)

您可以使用零宽度模式和反向引用来执行此操作:

\(\%(^\t\)\@<==\{3}\|\%([ ]\{5,}^\)\@<=-\{3}\)\_$

零宽度模式允许您将模式从匹配某些字符转换为匹配位置。 \@<=只是说先前的模式发生在当前位置之前。

\zs是一种特殊情况,可让您简化以\%(...\)\@<=...\zs开头的任何模式。

另一种方法就是在替换中使用所有反向引用 - 来自不匹配分支的反向引用将扩展为空字符串:

:.s/^\t\(=\)\{3,}\_$\|[ ]\{5,}^\(-\)\{3,}\_$/apple\1\2banana/e