Vim 搜索和替换详解
Vim 提供了强大的搜索和替换功能,掌握这些技巧能极大提高编辑效率。
一、基础搜索
1. 单文件搜索
/pattern " 向前搜索(向下)
?pattern " 向后搜索(向上)
示例:
/hello " 搜索 "hello"
?world " 向上搜索 "world"
2. 导航搜索结果
n " 跳转到下一个匹配项
N " 跳转到上一个匹配项
* " 搜索当前光标下的单词(向前)
# " 搜索当前光标下的单词(向后)
3. 搜索选项
:set ignorecase " 忽略大小写 (ic)
:set smartcase " 智能大小写(有大写时区分)
:set noignorecase " 不忽略大小写 (noic)
" 临时忽略大小写
/\chello " 区分大小写搜索
/\chello\c " 不区分大小写搜索
二、高级搜索模式
1. 正则表达式搜索
/^hello " 以 hello 开头的行
/end$ " 以 end 结尾的行
/^$ " 空行
/^\s*$ " 空白行(可能包含空格/tab)
2. 字符类
/[abc] " 匹配 a、b 或 c
/[0-9] " 匹配数字
/[a-zA-Z] " 匹配字母
/\d " 数字(同 [0-9])
/\w " 单词字符(字母、数字、下划线)
/\s " 空白字符(空格、tab)
3. 量词
/ab\{2,4} " ab 重复 2-4 次:abb、abbb、abbbb
/ab\{3,} " ab 至少重复 3 次
/ab\{,3} " ab 最多重复 3 次
/ab\{2} " ab 重复 2 次:abb
/ab* " a 后面跟 0 或多个 b
/ab\+ " a 后面跟 1 或多个 b
/ab\= " a 后面跟 0 或 1 个 b
4. 分组和或操作
/\(foo\|bar\) " 匹配 foo 或 bar
/one\|two\|three " 匹配 one、two 或 three
/\(ab\)\{3} " 匹配 ababab
三、替换命令详解
1. 基本替换语法
:[range]s/pattern/replacement/[flags]
示例:
:s/foo/bar/ " 当前行第一个 foo 替换为 bar
:s/foo/bar/g " 当前行所有 foo 替换为 bar
:2,5s/foo/bar/g " 第2-5行所有 foo 替换为 bar
:%s/foo/bar/g " 整个文件所有 foo 替换为 bar
2. 范围选择
:%s/foo/bar/g " 整个文件
:1,10s/foo/bar/g " 第1-10行
:.,$s/foo/bar/g " 从当前行到文件末尾
:'a,'bs/foo/bar/g " 标记 a 到 b 的行
:/start/,/end/s/foo/bar/g " 从匹配 start 到 end 的行
3. 替换标志
g " 全局替换(行内所有匹配)
c " 每次替换前确认
i " 忽略大小写
I " 不忽略大小写
e " 不显示错误(无匹配时不报错)
n " 只报告匹配数量,不实际替换
p " 打印替换的最后一行
四、确认替换(交互式)
1. 使用 c 标志
:%s/old/new/gc
交互提示:
replace with new (y/n/a/q/l/^E/^Y)?
- y - 替换这个匹配
- n - 跳过这个匹配
- a - 替换所有匹配(不再询问)
- q - 退出替换
- l - 替换这个匹配后退出
- Ctrl+E - 向上滚动
- Ctrl+Y - 向下滚动
2. 实际示例
" 文件内容:
" hello world
" hello vim
" HELLO everyone
:%s/hello/Hi/gc
" 提示1: replace with Hi (y/n/a/q/l/^E/^Y)? y # 替换第一行
" 提示2: replace with Hi (y/n/a/q/l/^E/^Y)? n # 跳过第二行(不区分大小写)
" 提示3: replace with Hi (y/n/a/q/l/^E/^Y)? a # 替换剩余所有
五、特殊替换功能
1. 使用替换内容
:%s/\(hello\) \(world\)/\2 \1/ " 交换 hello 和 world
:%s/hello/\U&/g " HELLO(转大写)
:%s/HELLO/\L&/g " hello(转小写)
:%s/hello/\u&/g " Hello(首字母大写)
2. 特殊字符
\r " 插入换行符
\t " 插入制表符
\\ " 插入反斜杠
\0 " 整个匹配
\1, \2, ... " 第n个分组
& " 整个匹配(同 \0)
六、复杂替换示例
示例1:重命名变量
" 把 variableName 改为 newVarName
:%s/\<variableName\>/newVarName/g
" \< 和 \> 是单词边界,避免匹配到 variableNameLong 这样的词
示例2:格式化日期
" 把 YYYY-MM-DD 改为 MM/DD/YYYY
:%s/\(\d\{4\}\)-\(\d\{2\}\)-\(\d\{2\}\)/\2\/\3\/\1/g
" 2023-12-25 → 12/25/2023
示例3:删除行尾空格
:%s/\s\+$//g
示例4:删除空行
" 删除完全空的行
:g/^$/d
" 删除只包含空格的行
:g/^\s*$/d
示例5:添加行号
" 在每行开头添加行号
:%s/^/\=printf('%3d. ', line('.') )/
七、跨文件搜索
1. 使用 vimgrep
:vimgrep /pattern/ **/*.py " 搜索所有 .py 文件
:vimgrep /pattern/ % " 搜索当前文件
:vimgrep /pattern/ **/*.cpp **/*.h " 搜索多种文件类型
2. 使用 grep(外部命令)
:grep -r "pattern" . " 递归搜索
:grep -i "pattern" **/*.js " 忽略大小写搜索 js 文件
3. 导航搜索结果
:copen " 打开 quickfix 窗口
:cclose " 关闭 quickfix 窗口
:cnext " 下一个匹配
:cprev " 上一个匹配
:cc " 查看当前匹配
八、实用技巧
1. 搜索历史
q/ " 打开搜索命令历史
q: " 打开命令历史
2. 高亮搜索
:set hlsearch " 开启高亮
:set nohlsearch " 关闭高亮
:nohlsearch " 临时关闭当前高亮
3. 增量搜索
:set incsearch " 输入时实时显示匹配
4. 搜索后居中显示
:set scrolloff=5 " 光标上下保留5行
九、练习示例
创建一个测试文件 test.txt:
hello world
hello vim
Hello World
HELLO everyone
foo hello bar
hello
world hello test
练习1:基础搜索
/hello " 搜索 hello
n " 下一个
N " 上一个
练习2:全局替换
:%s/hello/HI/g " 全部替换
:u " 撤销
练习3:确认替换
:%s/hello/HI/gc " 交互式替换
练习4:大小写转换
:%s/hello/\U&/g " HELLO
:%s/HELLO/\L&/g " hello
十、常见问题
1. 特殊字符转义
" 搜索包含 . * [ ] 等特殊字符
/example\.com " 搜索 example.com
/a\*b " 搜索 a*b
/\[test\] " 搜索 [test]
2. 替换中的特殊字符
" 要在替换文本中使用 / 需要转义
:%s/path/\/usr\/local\/bin/g
" 或使用其他分隔符
:%s#path#/usr/local/bin#g
:%s@path@/usr/local/bin@g
3. 性能优化
" 大文件搜索优化
:set nohlsearch " 关闭高亮
:set lazyredraw " 延迟重绘
十一、记忆技巧
- 搜索方向 :
/向下,?向上 - 导航 :
n下一个,N上一个 - 替换范围 :
%全部,1,5第1-5行 - 全局替换 :
g标志 - 确认替换 :
c标志
通过大量练习,你会逐渐掌握这些搜索和替换技巧,极大提高在 Vim 中的编辑效率。