5月27日 14:50

Vim 搜索和替换有哪些必须掌握的高级技巧?

Vim 的搜索能力远不止输入关键词然后按回车。正则元字符模式、搜索高亮策略、替换确认机制、跨文件搜索——这些才是真正拉开效率差距的地方。

用 / 和 ? 精准定位

/ 向下搜索,? 向上搜索,这是最基本的区分。按 n 跳到下一个匹配,N 跳到上一个(在 ? 搜索时方向反转)。

搜索当前光标下的单词有两个快捷操作:* 向下搜索整个单词,# 向上搜索。Vim 会自动给关键词加上 \<\> 边界,不会匹配到包含该单词的更长字符串。

如果只想搜索光标下单词的部分匹配(不要求单词边界),用 g*g#

四种正则模式:\v \V \m \M

Vim 的正则语法有四种模式,这是很多人忽略的关键机制:

  • \m(magic):默认模式。.*^$ 等有特殊含义,但 +?(){}| 需要反斜杠转义才生效。写分组是 \(\),或逻辑是 \|
  • \v(very magic):所有元字符都直接生效,不需要反斜杠。写分组直接用 (),或逻辑直接用 |,量词直接用 +?。这是最接近 Perl 正则的模式,写复杂表达式时强烈推荐。
  • \M(nomagic):只有 ^$ 有特殊含义,其余字符全部当作字面量。
  • \V(very nomagic):只有反斜杠本身有特殊含义,搜索的就是字面文本。当你需要搜索包含大量特殊字符的字符串时,用这个模式最省心。

实际用法是在搜索模式开头加上模式修饰符:/\v\d+\.\d+ 匹配浮点数,/\Vfoo.bar 搜索字面的 "foo.bar"。

搜索高亮:hlsearch 和 incsearch

两个选项控制搜索时的视觉反馈:

vim
set hlsearch " 高亮所有匹配项 set incsearch " 输入时实时跳转到第一个匹配

hlsearch 打开后,最后一次搜索的所有匹配都会高亮显示。缺点是高亮会一直留在屏幕上,用 :nohlsearch(简写 :noh)临时关闭。很多人在 vimrc 中映射一个快捷键:

vim
nnoremap <Esc><Esc> :nohlsearch<CR>

连按两次 Esc 清除高亮。

incsearch 让你在输入搜索模式的过程中就能看到当前匹配位置,不用等按回车。这对复杂正则特别有用,输入到一半就能判断模式是否正确。

替换命令 :s 和 :%s

基本语法:

vim
:s/old/new/ " 当前行替换第一个匹配 :s/old/new/g " 当前行替换所有匹配 :%s/old/new/g " 全文替换 :5,20s/old/new/g " 第5行到第20行替换

范围除了行号,还支持这些写法:

  • .,$s — 从当前行到文件末尾
  • 1,.s — 从第一行到当前行
  • '<,'>s — 可视模式下选中区域(按 : 自动填充)

确认替换:c 标志

替换最怕改错地方。加 c 标志让每次替换前都确认:

vim
:%s/old/new/gc

Vim 会逐个高亮匹配,提示你选择:

  • y — 替换当前
  • n — 跳过当前
  • a — 替换剩余全部
  • q — 退出替换
  • l — 替换当前后退出

这个交互流程让大规模替换变得安全可控。

正则捕获与反向引用

\( \) 分组(magic 模式)或 () 分组(very magic 模式),替换时用 \1\2 引用捕获内容:

vim
" 将 "lastName, firstName" 改为 "firstName lastName" :%s/\v(\w+),\s*(\w+)/\2 \1/g

这里 \1 是第一个括号匹配的内容(姓),\2 是第二个(名)。

另一个实用场景——给函数调用加引号:

vim
:%s/\vfunc\(([^)]+)\)/func("\1")/g

大小写控制:\c 和 \C

在搜索模式中直接加修饰符比改设置更灵活:

  • /pattern\c — 忽略大小写搜索
  • /pattern\C — 强制区分大小写

也可以配合 ignorecasesmartcase 选项:

vim
set ignorecase " 默认忽略大小写 set smartcase " 搜索模式中包含大写字母时自动区分大小写

smartcase 的逻辑是:如果你特意输入了大写字母,说明你要精确匹配,否则就忽略大小写。这个组合比单独用 ignorecase 更智能。

搜索历史的复用

Vim 保存搜索历史,在搜索模式下按上下方向键可以回溯之前的搜索模式。更高效的做法是先输入部分内容再按上下键,Vim 只显示以该内容开头的历史条目。

命令行窗口是另一个利器:按 q/ 打开搜索历史窗口,q: 打开命令历史窗口。在这个窗口中可以用 Vim 的全部编辑能力修改历史命令,然后按回车执行。

跨文件搜索::vimgrep

当搜索范围需要超出当前文件:

vim
:vimgrep /pattern/ **/*.py

这会递归搜索当前目录下所有 .py 文件。搜索结果进入 quickfix 列表。

常用操作:

  • :copen — 打开 quickfix 窗口
  • :cnext / :cprev — 在匹配项之间跳转
  • :cfirst / :clast — 跳到第一个/最后一个匹配
  • :cclose — 关闭 quickfix 窗口

也可以指定文件范围:

vim
:vimgrep /TODO/ src/**/*.js :vimgrep /FIXME/ *.c

quickfix 列表不只服务于 vimgrep,:grep、编译错误等都会用到同一套导航命令,值得记住。

从搜索到替换的实战流程

一个高效的工作流是先搜索验证,再替换执行:

  1. /pattern 搜索,n 逐个检查匹配是否符合预期
  2. 确认无误后直接执行 :%s//replacement/g——注意搜索模式留空,Vim 自动使用最后一次搜索的模式
  3. 不确定时加 c 标志逐步确认

这个流程把搜索和替换打通,避免了在替换命令中重新输入复杂正则的麻烦。

Vim 的搜索体系从单文件关键词到跨文件正则,覆盖了文本定位的完整链路。掌握这些技巧后,日常编辑中的查找替换操作会从反复试错变成一次到位。

标签:Vim