上次我们用宏操作的方式在VIM中由一行代码批量生成了一系列相似的代码,原文在这里
这次我们用正则表达式的方式实现批量替换
把上次的小练习先贴出来
在GVIM下,将下面这张图的内容

改成下面这样

并且指出,要用批量操作的方式,不能一行一行的键入
在给出实现方法之前,先给出VIM中各种符号的意义
| 普通字符 | 含义 |
|---|---|
| . | 匹配任意一个字符 |
| [abc] | 匹配方括号中的任意一个字符,可以使用 - 表示范围比如[a-z0-9]匹配小写字母和数字 |
| [^abc] | 匹配除方括号中字符以外的字符 |
| \d | 匹配阿拉伯数字,等同于[0~9] |
| \D | 匹配阿拉伯数字之外的任意字符,等同于[^0~9] |
| \x | 匹配十六进制数字,等同于[0-9A-Fa-f] |
| \X | 匹配十六进制数字之外的任意字符,等同于[ ^0-9A-Fa-f] |
| \w | 匹配单词字母 |
| \W | 匹配单词字母之外的任意字符 |
| \t | 匹配Tab字符 |
| \s | 匹配空白符,等同于[\t] |
| \S | 匹配非空白符,等同于[ ^\t] |
| 特殊字符 | 含义 |
|---|---|
| \ * | 匹配 * 字符 |
| \ . | 匹配 . 字符 |
| \ / | 匹配 / 字符 |
| \ \ | 匹配 \ 字符 |
| \ [ | 匹配 [ 字符 |
| 表示数量的元字符 | 含义 |
|---|---|
| * | 匹配0~任意个 |
| \ + | 匹配1~任意个 |
| \ ? | 匹配0~1个 |
| \ {n,m} | 匹配n ~ m个 |
| \ {n} | 匹配 n 个 |
| \ {n,} | 匹配 n ~ 任意个 |
| \ {,m} | 匹配 0 ~ m 个 |
| 表示位置元字符 | 含义 |
|---|---|
| $ | 匹配行尾 |
| ^ | 匹配行首 |
| \ < | 匹配单词词首 |
| \ > | 匹配单词词尾 |
现在回到那个小练习,由于我们主要用正则来进行替换,因此我们先将第一行内容进行复制粘贴
在普通模式下
gg //回到首行
yy //复制首行内容
19p //粘贴19次

之后变成这样了
再进行替换之前,介绍下VIM替换的方式
替换的格式为
:s/a/b/g //将a替换成b
//s是substitute,g是global
我们先gg回到首行,然后看看加上g和不加g的区别
命令行执行如下内容
:s/1/aa/

可以看到,只有第一行的第一个1变成了aa
再执行如下内容
u //undo,撤销上一步操作
:s/1/aa/g

可以看到此时首行所有的1都被替换成了aa
虽然加上g将首行的1全部替换成了aa,但也只有首行被替换了,如果多行都需要替换,我们不可能在每一行都执行这个操作,因此引入了%
我们执行下面的内容看看是什么结果
u //撤销上一步操作
:%s/1/aa/

可以看到此时每行的第一个1都被替换成了aa
如果我们只想替换其中几行的内容,可以将%换成范围
:5,8s/1/aa/

此时只有5-8行的1被替换了
由于我们这个小练习被替换成的内容不是固定的,因此需要再介绍一个函数
\=line(".")
这个函数是获取行号的意思,并且可以进行加减乘,如果想在当前行上加n,只需要
\=ling(".")+n
先试一下,将首行的2改成行号×10
:s/2/\=line(".") * 10/

首行的2成功被替换成了10
准备工作结束,下面直接直接给出批量更改的正则表达式
:%s/\d/\=line(".")/
:%s/\d$/\=line(".") + 1/
执行第一个指令的结果

随后执行第二个指令的结果

大功告成
最后再讲一下这两个指令的含义吧
首先是第一个指令
:%s/\d/\=line(".")/
%s:所有行进行替换
\d:第一个数字
\=line("."):获取行号
第二个指令
:%s/\d$/\=line(".") + 1/
%s:所有行进行替换
\d$:最后一个数字,$是位置元字符,表示行位
\=line(".") + 1:获取行号并 + 1
本文详细介绍了如何使用VIM的正则表达式进行批量代码替换,从基本的正则符号含义到数量、位置元字符的用法,再到批量替换的实践操作,包括全局替换和范围替换。通过一个小练习,演示了如何利用行号函数=line('.')动态替换数字,实现了根据行号批量修改代码内容。
31

被折叠的 条评论
为什么被折叠?



