vi/vim使用技巧: 替换的巧妙使用(2)

上一篇文章中,我们使用了两条VIM替换命令,下面详细剖析一下这两条命令。

以第一条命令为例,第二条命令和第一条命令类似:

:'<,'>s/BIT_MASK_\zs\d*\ze/\=line(".") - line("'<") + 1 

这条命令在我们选中的区域内进行替换,查找以”BIT_MASK_”开头,后面跟任意多个数字的字符串,并把匹配位置放在数字上,然后使用后面表达式计算出来的数字替换这些匹配的数字。

下面是这条命令中每个元素的含义:

'<,'>        我们所选中的区域 (:help '<:help '> )
s            在选中的区域中进行替换 (:help :s )
\zs          指明匹配由此开始 (:help /\zs )
\d*          查找任意位数的数字 (:help /\d )
\ze          指明匹配到此为止 (:help /\ze )
\=           指明后面是一个表达式 (:help :s\= )
line(".")    当前光标所在行的行号 (:help line() )
line("'<")   我们所选区域中第一行的行号 (:help line() ) 

‘<和’>是我们使用了”v”,”V”命令选中一个visual区域后,VIM设置的标记,分别用来标识visual区域的开始和结束。

“BIT_MASK_\zs\d*\ze”是一个正则表达式,用来查找以”BIT_MASK_”开头,后面跟任意多个数字的字符串。其中”\zs”、”\ze”用来指定匹配的开始和结束位置,因为我们只打算替换”BIT_MASK_0″中的数字,所以在查找时只把匹配区域置在数字上。

由于我们的替换操作要把不同行的数字替换成不同的值,所以在这里需要使用一个表达式来计算出替换后的值。当”:s”命令的替换字符串是以”\=”开头时,表明使用一个表达式计算的结果进行替换。我们这里的表达式就是”line(“.”) – line(“‘<“) + 1″,其中”line()”函数用来获得行号,它可以获得当前行的行号,以及指定的标记(mark)所在的行号。”line(“.”)”用来获得当前光标所在行的行号,”line(“‘<“)”则用来获得”‘<“标记所在行的行号。这两个行号的差加上1就是我们想替换的值。

下一篇文章将介绍另外一种方法来完成同样的功能。

[参考文档]

  • VIM邮件列表,2007/01/29, 邮件标题:”replace with a number sequence”

“vi/vim使用技巧: 替换的巧妙使用(2)”的6个回复

  1. 后来想起其他regex 做法,可以用其他字符替代”/” 作为regex 分隔符,vim 应该也可以,呵呵。

  2. :help :s\= 找不到详细资料,不知道博主是否有遇到以下情况?
    ‘\=’ 指定的表示式中,如果有除以符号’/’的话,是否可以处理?
    还是另寻方法?

发表回复

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