您遇到的问题是\1
指当前替换的匹配组而不是:g
命令的模式。遗憾的是,您无法从以前的搜索中访问以前的匹配组。但是,有一些方法可以实现您的目标。我建议的第一个是宏。
首先从不匹配的行开始。这可以通过在需要时在文件顶部插入一个空行来完成(之后只需将其删除)。
- 开始宏搜索您的模式:
/name_\d\+
- 猛拉直到你的模式结束:
y//e
- 找到结束模式:
/end/e
- 插入下划线
a_
- 粘贴
p
- 结束你的宏
q
- 执行大量的宏。例如
999@q
这是我使用的宏:
:let @q = "/name_\\d\\+\<cr>y//e\<cr>/end/e\<cr>a_\<esc>p"
另一种方法是以:global
与您的尝试类似的方式使用该命令。
:g/name_\d\+/let @@=matchstr(getline('.'),'name_\d\+')|/end/s//\=submatch(0).'_'.@@/
我个人这太复杂了,但是有选择是很好的。该命令可以分解为以下部分:
:g/name_\d\+
在匹配 name_ 和某个数字的每一行上执行一个命令
getline('.')
将返回当前行的字符串
matchstr(getline('.'), 'name_\d\+')
将只返回当前行的匹配部分
let @@ = matchstr(...)
将匹配部分设置为默认寄存器
/end/s/
:s
将在匹配的以下行上执行 aend
s//\=.../
匹配最后使用的模式并用 express 替换它。
submatch(0).'_'.@@
创建一个包含整个匹配模式的字符串,后跟一个下划线和未命名寄存器的内容。
有关以下主题的更多信息,请参阅:
:h q
:h search-offset
:h :g
:h :let-@
:h registers
:h matchstr(
:h getline(
:h range
:h submatch(