vim中一些高级替换技巧

gotowqj 2012-02-25

 

1.替换变量

在正规表达式中使用\(和\)符号括起正规表达式,即可在后面使用\1、\2等变量来访问\(和\)中的内容。

example:

·将data1data2修改为data2data1

-----------------------------------

:s/\(\w\+\)\s\+\(\w\+\)/\2\t\1

-----------------------------------

·将Doe,John修改为JohnDoe

-----------------------------------

:%s/\(\w\+\),\(\w\+\)/\2\1/

-----------------------------------

2.利用函数式替换

用法:

---------------------------

:s/替换字符串/\=函数式

---------------------------

说明:

·函数式可以有多个,返回值可以用字符串连接符.连接起来,如line(".")返回匹配行号(:helpline()),submatch(n)可以引用\1、\2的内容,其中submatch(0)引用匹配的整个内容;

·函数式也可以是字符串常量,用双引号引起来。函数式也可以是任意表达式,需要用小括号引起来,如(3+2*6);

·函数式还可以是寄存器中的内容,通过"@寄存器名"访问,如@a(不需要加引号,但是还是需要用.来连接);

example:

·要将下列8行的data0依次变成data0~7(前面的数字是行号)

doubledata0;

doubledata0;

doubledata0;

doubledata0;

doubledata0;

doubledata0;

doubledata0;

doubledata0;

如果安装有perl的话,我以前一般都是借助perl来完成这件事情:

---------------------------------------------------------------------------

:r!perl-n-le"if(s/^(double\s+data)\d;/$1$k;/){$k++;print$_;}"%:p---------------------------------------------------------------------------

其中%:p表示包含完整路径的文件名

现在只用vim我们就可以完成这样的事情:

首先将光标移到125行(line(".")返回当前匹配行的行号,line("'a")返回marka的行号):

---------------------------------------------------------------------------

ma

:%s/^\(double\s\+data\)\d\(;\)/\=submatch(1).(line(".")-line("'a")+1).submatch(2)/g

---------------------------------------------------------------------------

再或者

首先将光标移到125行(line("'V7j

:%s/^\(double\s\+data\)\d\(;\)/\=submatch(1).(line(".")-line("'

---------------------------------------------------------------------------

3.匹配的开始与结束

\zs和\ze可以用于替换操作中指明替换的开始与结束,如上例中可以以更短的操作来实现:

---------------------------------------------------------------------------

ma

:%s#^double\s\+data\zs\d\ze#\=(line(".")-line("'a")+1)#g

---------------------------------------------------------------------------

另外,还可以使用vim表达式来实现上述功能:

---------------------------------------------------------------------------

:letn=0|g/^double\s\+data\zs\d/s//\=n/|letn+=1

---------------------------------------------------------------------------

其中·|用来分割不用的命令;

·g在匹配后面模式的行中执行指定的ex命令

·\zs指明匹配由此开始

·s//\=n对匹配模式进行替换,匹配模式为空,表示以上一次匹配成功的模式,

并且指明替换是一个表达式;

4.高级递增替换

把下面几句放到_vimrc

-------------------------------

letg:I=0

function!INC(increment)

letg:I=g:I+a:increment

returng:I

endfunction

------------------------------

·对于上述问题,可以这样解决:

-----------------------------------------------------

:letI=-1|%s/^double\s\+data\zs\d\ze/\=INC(1)/

-----------------------------------------------------

·还可以生成数字序列,如生成1~100间隔为5的数字序列:

--------------------------------------

:letI=0|‘a,’bs/^/\=INC(5)/

--------------------------------------

Normal

0

7.8磅

0

2

false

false

false

EN-US

ZH-CN

X-NONE

相关推荐