ctrl+h(win/linux)或cmd+option+f(macos)仅作用于当前激活的编辑器标签页,而ctrl+shift+h(win/linux)或cmd+shift+h(macos)默认扫描整个工作区未打开文件,需手动展开replace区域、启用正则及处理只读/排除文件。

Ctrl+H 和 Ctrl+Shift+H 的作用范围完全不同
Ctrl+H(Windows/Linux)或 Cmd+Option+F(macOS)只在当前**已打开的编辑器标签页**中查找并替换,哪怕你打开了 20 个文件,它也只动当前激活的那个。而 Ctrl+Shift+H(Windows/Linux)或 Cmd+Shift+H(macOS)是真正意义上的“全局替换”,默认扫描整个工作区目录树——包括所有子文件夹里未打开的文件,只要它们没被 .gitignore 或 VSCode 的 files.exclude 排除。
全局替换前必须手动展开 Replace 区域
很多人按了 Ctrl+Shift+H 输完内容直接回车,结果界面上根本没有“全部替换”按钮——因为 VSCode 默认只显示搜索面板,替换功能是隐藏的:
- 必须点击搜索框下方的 Replace 标签,或按
Alt+R(Win/Linux)/Option+R(macOS)手动展开替换输入框 - 不展开,
Replace All按钮根本不会出现,快捷键也不会触发替换逻辑 - 即使展开了,如果光标不在搜索框内(比如卡在终端或调试控制台),快捷键也会失效
全局替换不会自动保存,且跳过只读文件
Ctrl+Shift+H 执行的是内存级修改:替换完成后,所有被改过的文件标题栏会显示 ●,但内容仍停留在编辑器缓冲区,不会写入磁盘:
- 必须逐个按
Ctrl+S,或用Ctrl+Shift+S保存全部已修改文件 - 如果某个匹配文件是只读状态(右下角显示 Read-only),
Replace All会直接跳过它,不会报错、也不会提示 - 未保存的临时文件(如通过
Ctrl+P新建未命名的 untitled-* 文件)同样被忽略
正则捕获组在两种模式下写法一致,但启用方式不同
无论是 Ctrl+H 还是 Ctrl+Shift+H,正则替换都只认 $1,不支持 \1;要输出字面量 $ 得写成 $$。但关键区别在于启用正则的路径:
-
Ctrl+H启动后,右下角.*图标默认不亮,必须手动点它或按Alt+R开启,否则\d+、^全当普通字符处理 -
Ctrl+Shift+H同样依赖这个开关,而且它的正则模式是全局持久的——一旦开启,后续所有搜索(包括再按Ctrl+F)都会沿用该状态 - 跨行匹配需要额外勾选
.*旁的[\s\S]*按钮(即 dotAll 模式),否则.*遇到换行就停住
全局替换真正麻烦的不是操作步骤,而是它默认不告诉你哪些文件被跳过了——比如 node_modules 里的匹配项不会出现在结果列表里,除非你手动清空 Files to exclude 并关掉 Use Exclude Settings。这点很容易被忽略,直到你发现改了十次都没生效。











