PAYATHON 2026

如何在 Vim/Neovim 中复制多行文本并批量替换相同内容?

数据小陈

可以。先把需要替换的多行文本 yank 到寄存器,转换成搜索模式后执行 :%s。这样不用为每个文本块手写正则表达式,也不用安装插件。

1. 复制完整的列表表达式

在普通模式下,将光标放到 foo([ 中的 [ 上,输入:

"ay%

这会将从 [ 到对应 ] 的内容复制到寄存器 a,包括中间的换行,但不包括外层的 foo( 和 )。

对于其他形状的表达式,可以用字符可视模式 v 选中完整内容,再输入 "ay。应避免使用整行可视模式 V,否则可能把函数名、外层括号或末尾换行一起复制进去。

2. 将寄存器内容转换为搜索模式

在同一行输入并执行以下命令:

:let @/ = '\V\C' . substitute(escape(@a, '\'), "\n", '\\n', 'g')

其中:

  • @a 是刚才复制的文本。
  • escape(@a, '\') 转义原文本中的反斜杠,避免它们被解释为正则指令。
  • substitute(..., "\n", '\\n', 'g') 将实际换行转换为匹配模式中的 \n。
  • \V 启用 very nomagic,使方括号、圆括号、点号等按字面匹配。
  • \C 强制区分大小写。
  • @/ 是搜索寄存器,用来保存生成的模式。

在 \V 下,反斜杠仍有特殊含义,因此不能省略转义;跨行匹配需要保留表示行边界的 \n。这些规则见 Vim 搜索模式文档。

3. 批量替换为变量名

接着执行:

:%s//my_vars/gc

命令中省略了匹配模式,会直接使用刚设置的搜索模式。% 表示整个文件,g 在默认设置下替换每行内的所有匹配,c 要求逐个确认。确认时按 y 替换当前匹配,按 n 跳过,按 a 替换所有剩余匹配。空模式的复用规则和确认标志见 Vim 替换命令文档。

如果不需要逐个确认,可以使用:

:%s//my_vars/g

执行前不要插入其他搜索操作,以免覆盖刚设置的搜索模式。

4. 添加变量定义

先完成替换,再添加变量定义,避免新定义中的列表也被替换为 my_vars。

寄存器 a 仍保存着原列表。先将它粘贴到文件顶部:

:0put a

再给第一行加上赋值前缀:

:1s/^/my_vars = /

根据需要添加空行后,结果如下:

my_vars = [
"var1",
"var2",
"var3",
]

foo(my_vars)

bar(my_vars)

:put 会按整行方式插入寄存器内容,因此可以把以字符方式复制的列表作为独立代码块插入。具体行为见 Vim 的

文档。

注意匹配范围

这个方案按文本匹配,空格、缩进和换行位置都需要一致。内容相同但格式不同的表达式不会自动视为同一个匹配。

替换操作不会分析作用域或程序语义。提取后应确保 my_vars 在调用处可见;如果列表会被修改,还需要确认多个调用共享同一个列表是否符合预期。

如果把替换内容改成其他字符串,替换侧的 &、反斜杠和分隔符仍需按 :substitute 的规则处理,\V 只控制匹配侧。

备注:内容仅供参考。