VIM查找替换

VIM查找替换

在VIM当中,substitute命令是一个好用且强大的功能,它的潜力被很多VIM用户所忽略,这里将会盘点一下substitute命令的使用方式和一些常用场景

一、初始substitute命令

使用help命令查看:substitute或者:s,可以查看详细手册,建议配合手册食用本教程

首先让我们看看:s命令是什么样子的:

:[range]s[ubstitute]/{pattern}/{string}/[flags] [count]

嘶,看上去有点恐怖,好复杂啊,还是放弃吧没关系,让我们一起来慢慢拆分各个板块。首先,[]的内容是可以省略的,它们有默认行为;{}的内容是不可省略的,需要自己填

1.1 [range]

[range]是表示匹配的范围,这一个板块可以省略,默认是.,表示匹配当前行。其他参数如下:

  • %:匹配整个文件
  • number:行号,匹配特定行
  • .:默认项,匹配当前行
  • $:匹配最后一行
  • '<,'>:在Visual模式下选中的范围
  • ,:分割两个行号,表示匹配范围。如:1,5s/f/t,匹配的范围是1-5行
  • ;:类似,,但是采用相对行号。如:1,+10s/f/t,匹配从1行开始,往下10行

1.2 [flags]

[flags]表示替换的标志,不同的标志都有不同的功能

  • g:全局替换。1,5s/f/t会将1-5行中,每行第一个f替换为t;使用1,5s/f/t/g则是将1-5行中所有的f都替换为t
  • c:确认替换。每次替换匹配项之前,都会询问是否替换
    • y:替换当前匹配项
    • n:不替换当前匹配项
    • a:替换当前以及后面所有匹配项
    • q:退出替换
    • l:替换当前匹配并退出
  • i:忽略大小写
  • I:不忽略大小写
  • n:不替换内容,打印匹配的数量
  • e:关闭警告。没找到匹配项的时候不警告,可以防止打断

1.3 [count]

没啥用的功能。一个数字,表示从 [range] 的最后一行的开始,再向下替换 [count] 行

1.4 {pattern}与

表示匹配项与替换字符串,现在会用基本的字符串即可,下面讲解和正则的结合使用

二、substitute参数与vim正则

2.1 pattern正则

pattern支持强大的Vim 正则表达式。这是精准替换的前提

  • ^$:匹配行首和行尾
  • .:匹配任何单个字符
  • \s\S:匹配空白/非空白字符
  • \w\W:匹配单词/非单词字符
  • 数量匹配符:
    • *:前一个字符出现任意次数,可以为0。如:a*b可以匹配babaab……
    • \+:前一个字符出现1次或多次
    • \?:前一个字符出现0次或1次
    • \{n,m}:前一个字符出现至少n次,至多m次,n和m可以忽略一个
  • \|:“或”操作
  • \(\):分组。可以用来匹配连续字符,分组的内容可以在替换字符串中用\1,\2,...来引用。这个后面详解
  • \<\>:匹配完整单词。<lua>会匹配"lua ls"中的"lua",但是不会匹配"lua_ls"中的"lua"
  • []:匹配字符
  • \zs:表示匹配起始地点
  • \@<=:正向后瞻,确保前面有第一个pattern

案例:

  1. 删除全文的行尾空格
    • 命令::%s/\s\+$//
    • 详解:\s匹配空白符,加上\+表示匹配多次,再加上$表示行尾。意思是,匹配以行尾结束的连续空白符号
  2. 删除"="两边多余的空格,只留下一个
    • 命令::s/\s\+=\s\+/ = /g
  3. 删除所有的数字
    • 命令::s/[0-9]//g
  4. 删除所有不是0的字符替换成s
    • 命令::s/[^0]/s/g
  5. 将"- \t : 插入制表符"中除了"- "外所有空格删除
    • 命令::s/[^-]\zs\s\+//g
    • 详解:[^-]表示不是-的所有字符;\zs表示从不是"-"的字符开始匹配;\s\+如上
  6. 将"java is not the best language, cpp is the best language",中第二个"best"替换成"exact best"
    • 命令::s/\(best.*\)\@<=best/exact best/
    • 详解:\(best.*\)表示best开头的字符串。\@<=表示前面存在best开头的字符串。则\(best.*\)\@<=best表示第二个best

2.2 替换字符串中的特殊字符

string 中,你可以使用以下转义序列来插入特殊内容:

  • \0&:插入整个匹配的文本
  • \1,\2,...\9:插入第n个分组\(...\)中匹配的文本
  • \r:插入换行符,从而将一行拆成两行
  • \n:插入一个<NUL>字符(不是换行)
  • \t:插入制表符
  • \\:插入一个反斜杠\
  • \u:将下一个字符转换为大写
  • \U:将其后所有字符转换为大写,直到\e\E
  • \l\L:同上,转换为小写

案例:

  1. markdown文件中,三级标题的形式为"### 1"、"### 2"……,将其改成"### 1.1"、"### 1.2"……
    • 命令:s/^###\s\zs[0-9]/1.\0/
    • 详解:pattern内容见上文。\0表示匹配到的数字
  2. 给"hello world"的hello加上[]
    • 命令:s/hello/[\0]/
  3. 将"int b = a > 10 ? func1() : func2();"中,三目运算符的两个表达表达式互换
    • 命令:s/\(.*\) ? \(.*\) : \(.*\);/\1 ? \3 : \2;

2.3 函数

是的你没看错,在vim的替换中还可以使用函数,使用的就是\=+函数名

众所周知,在vim当中可以使用line('.')来获取行号,那么,如果我们想在一个文件的每一行开头加上行号,可以使用下面的命令:

%s/^/\=line('.')/g

这样可能不太美观,咱们加上一点美化,在行号后面加上". "

%s/^/\=line('.').'. '/g

2.4 重复

使用重复字符可以节省时间:

  • ~:在当前行重复上一次替换,可以添加新标志
  • &:在当前行重复上一次替换,但不使用标志
  • :&&:在当前行重复上一次替换,并使用上一次的标志
  • g&:在整个文件范围内重复上一次替换,并使用上一次的标志。相当于:%s//~/&
  • :s或:~:使用新的搜索模式,但使用上一次的替换字符串和标志

三、cmdterm

cmdterm并不是substitute中的内容,但是在写正则的时候还是挺好用的

区别于cmdline,cmdterm虽然也是编辑cmd命令,但是是用vim模式下书写的,可以切换成normal模式,方便编辑。

使用方式:cmdline模式下按下

posted @ 2025-11-04 04:18  KicamonIce  阅读(19)  评论(0)    收藏  举报