VI 表达式替换

vi的查找替换中,有一种很有用的替换模式,就是查找替换,在要替换的字符中\=后面的字符串将会被解释为表达式,这个在替换中很有作用,比如说:

aa = 2

bb = 3

如果现在要把等号后面的数字都加上5 , 那么替换表达式可写成:
:% s/\m\(\d*\)/\= eval(submatch(1) + 5)/g

其中eval是vi的系统函数,表示对参数求值,而submatch(1)表示第一个匹配的字符串,eval这句话的意思就是对第一个匹配的数字加上5.

注意这里的submatch(1) , 通常,如果不是在函数中,可以直接用\1来替代,但是在函数中用\1会出问题。

另外submatch(0)表示整个匹配的字串。

一个有用的例子是:

RF32_GF32_BF32_A32
RS32_GS32_BS32_A32
RU32_GU32_BU32_A32
R16_G16_B16_A16

如果想要把每行中的数字都加起来就可以这样做:

:% s/\m\h*\(\d*\)\h*\(\d*\)\h*\(\d*\)\h*\(\d*\)/\=submatch(0) . ” ” . eval(submatch(1) + submatch(2) + submatch(3) + submatch(4))/g

结果是:
RF32_GF32_BF32_A32 128
RS32_GS32_BS32_A32 128
RU32_GU32_BU32_A32 128
R16_G16_B16_A16 64

 

另一个例子:使用到getline 和line 函数, 功能是找到数字的行,然后用其下面第二行的数字减去这个数字

1111
ssss
2222
eeee
3333

:% s/\m\(\d\+\)/\= submatch(1) . ” ” . eval(getline(line(“.”)+2) – submatch(1)) /g

其中line(“.”)得到当前行号,getline得到下面第二行,然后在减去当前行的值。 问题是vi中无法处理浮点数。为了处理浮点数,需要利用外部的程序,在利用system函数的过程中,注意这个函数的使用方法:

:. s#\m\(\d\+\)#\= submatch(1) .” ” . system(“~/float_substract” . ” ” . submatch(1) . ” ” .  getline(line(“.”) +2)#g

其中system函数的参数是一个表达式,其中的submatch(1)是float_substract 的第一个参数,getline是第二个参数,因此这里的float_substract 是一个普通c程序写成的可执行文件。



本文地址: http://www.bagualu.net/wordpress/archives/3044 转载请注明




发表评论

电子邮件地址不会被公开。 必填项已用*标注