搜索与替换
搜索与替换是文本编辑中最常用的功能之一。Vim 提供了强大的搜索和替换功能,支持正则表达式,能够高效处理大量文本。
搜索
基础搜索
| 命令 | 作用 |
|---|---|
/{pattern} | 向前搜索 |
?{pattern} | 向后搜索 |
n | 跳到下一个匹配 |
N | 跳到上一个匹配 |
示例:
/function " 向前搜索 function
?variable " 向后搜索 variable
n " 下一个匹配
N " 上一个匹配
搜索当前单词
| 命令 | 作用 |
|---|---|
* | 向前搜索光标下的完整单词 |
# | 向后搜索光标下的完整单词 |
g* | 向前搜索光标下的部分匹配 |
g# | 向后搜索光标下的部分匹配 |
区别:
*只匹配完整单词(如搜索the不会匹配then)g*匹配部分(如搜索the也会匹配then)
搜索选项
设置搜索行为:
:set hlsearch " 高亮所有匹配
:set nohlsearch " 关闭高亮
:set incsearch " 增量搜索(输入时实时显示)
:set ignorecase " 忽略大小写
:set smartcase " 智能大小写(有大写字母时区分大小写)
:set wrapscan " 循环搜索(到文件末尾后从头开始)
临时关闭高亮:
:noh 或 :nohlsearch " 临时关闭高亮,下次搜索重新开启
特殊字符搜索
搜索特殊字符需要转义:
/\. " 搜索点号
/\* " 搜索星号
/\$ " 搜索美元符号
/\\ " 搜索反斜杠
/\/ " 搜索斜杠
正则表达式搜索
Vim 支持强大的正则表达式:
/^hello " 搜索行首的 hello
/world$ " 搜索行尾的 world
/^$ " 搜索空行
/\<word\> " 搜索完整单词 word
/f[aei]st " 搜索 fast, fest, fist
/a\.\+b " 搜索 a 和 b 之间有任意字符
替换
基础替换命令
替换命令格式:
:[范围]s/旧文本/新文本/[标志]
示例:
:s/old/new/ " 替换当前行第一个匹配
:s/old/new/g " 替换当前行所有匹配
:%s/old/new/g " 替换整个文件所有匹配
:5,10s/old/new/g " 替换第 5-10 行
范围指定
| 范围 | 含义 |
|---|---|
| 无 | 当前行 |
% | 整个文件 |
n | 第 n 行 |
n,m | 第 n 到 m 行 |
. | 当前行 |
$ | 最后一行 |
n,$ | 第 n 行到末尾 |
'+a | 标记 a 所在行 |
'+a,'+b | 标记 a 到标记 b |
示例:
:1,50s/foo/bar/g " 替换 1-50 行
:.,$s/foo/bar/g " 从当前行到末尾
:'a,'bs/foo/bar/g " 从标记 a 到标记 b
替换标志
| 标志 | 含义 |
|---|---|
g | 全局替换(每行所有匹配) |
c | 每次替换前确认 |
i | 忽略大小写 |
I | 区分大小写 |
n | 只计数,不实际替换 |
e | 无匹配时不显示错误 |
确认替换时的选项:
y - 替换当前匹配
n - 跳过当前匹配
a - 替换所有剩余匹配
q - 退出替换
l - 替换并退出
Ctrl+e - 向上滚动
Ctrl+y - 向下滚动
实用替换示例
删除行尾空格:
:%s/\s\+$//g
删除空行:
:%s/^\n//g " 删除空行(简单版)
:g/^$/d " 删除空行(更好)
替换 Tab 为空格:
:%s/\t/ /g " 一个 Tab 换 4 个空格
在行首添加注释:
:5,20s/^/# /g " 5-20 行添加 # 注释
删除行首数字:
:%s/^\d\+\.\s*//g
全局命令
全局命令 g 对所有匹配行执行操作:
:[范围]g/模式/命令
示例:
:g/foo/d " 删除所有包含 foo 的行
:g!/foo/d " 删除所有不包含 foo 的行
:g/^$/d " 删除所有空行
:g/^#/y a " 复制所有以 # 开头的行到寄存器 a
:g/pattern/t$ " 复制所有匹配行到文件末尾
搜索与替换技巧
使用上次搜索模式
// " 使用上次搜索模式向前搜索
?? " 使用上次搜索模式向后搜索
:%s//new/g " 使用上次搜索模式进行替换
使用上次替换模式
:~ " 使用上次替换的搜索模式
:& " 重复上次替换
:&g " 重复上次替换,添加 g 标志
替换中的特殊符号
:%s/old/\r/g " \r 表示换行
:%s/old/\n/g " \n 表示空字符(在替换中)
:%s/old/&more/g " & 表示匹配的内容
:%s/\(.*\)/\1 copy/g " \1 表示第一个捕获组
可视化模式替换
在可视模式中选中区域后,按 : 会自动填充范围:
1. 选中要替换的区域(可视模式)
2. 按 :
3. 自动显示 :'<,'>(表示选中区域)
4. 输入 s/old/new/g
多文件搜索替换
使用参数列表
:args *.txt " 将所有 txt 文件加入参数列表
:argdo %s/old/new/gce " 在所有参数文件中进行替换
:argdo update " 保存所有修改的文件
使用缓冲区列表
:bufdo %s/old/new/gce " 在所有缓冲区中替换
使用窗口列表
:windo %s/old/new/gce " 在所有窗口中替换
搜索历史
查看和重用搜索历史
q/ " 打开搜索历史窗口(向前搜索)
q? " 打开搜索历史窗口(向后搜索)
在搜索历史窗口中:
- 按
Enter执行选中的搜索 - 可以编辑历史记录后执行
命令行历史
q: " 打开命令历史窗口
实战案例
案例 1:批量修改变量名
:%s/\<oldName\>/newName/g
使用 \< 和 \> 确保只替换完整单词。
案例 2:格式化列表
原始文本:
apple
banana
cherry
目标:变成 "apple", "banana", "cherry"
:%s/^/"/g " 行首添加双引号
:%s/$/"/g " 行尾添加双引号
:%s/\n/, /g " 换行符替换为逗号空格
案例 3:函数名重构
# 将 getUserName 改为 get_user_name
:%s/getUserName/get_user_name/g
# 更通用的驼峰转下划线(需要更复杂的正则)
:%s/\([a-z]\)\([A-Z]\)/\1_\L\2/g
案例 4:提取特定行
:g/console\.log/y A " 复制所有 console.log 到寄存器 A
:enew " 新建文件
"ap " 粘贴寄存器 a 的内容
案例 5:批量添加行号
:%s/^/\=line('.').'. '/g
结果:
1. 第一行
2. 第二行
3. 第三行
练习
练习 1:基础搜索
1. 打开任意代码文件
2. 用 / 搜索函数名
3. 用 n/N 浏览所有匹配
4. 用 * 搜索当前单词
5. 尝试 :set hlsearch 和 :set nohlsearch
练习 2:基础替换
1. 创建一个测试文件
2. 练习 :s/old/new/
3. 练习 :s/old/new/g
4. 练习 :%s/old/new/g
5. 练习带确认标志的替换 :%s/old/new/gc
练习 3:正则表达式
1. 搜索行首的单词:/^\w\+
2. 搜索行尾的标点:/[.!?]$/
3. 搜索空行:/^$/
4. 搜索包含数字的行:/\d\+
练习 4:实用替换
1. 删除文件中所有行尾空格
2. 删除所有空行
3. 将所有 Tab 替换为 4 个空格
4. 给所有行添加行号前缀
搜索替换总结
| 操作 | 命令 |
|---|---|
| 向前搜索 | /pattern |
| 向后搜索 | ?pattern |
| 下一个匹配 | n |
| 上一个匹配 | N |
| 当前行替换 | :s/old/new/g |
| 全局替换 | :%s/old/new/g |
| 确认替换 | :%s/old/new/gc |
| 删除匹配行 | :g/pattern/d |
| 复制匹配行 | :g/pattern/t$ |
下一步
搜索替换是 Vim 的强大功能,配合正则表达式可以处理复杂的文本操作。下一章我们将学习可视模式,这是进行选择性编辑的重要工具。