vim 匹配模式,然后使用该模式进行替换

vfwfrxfs  于 2023-11-19  发布在  其他
关注(0)|答案(2)|浏览(135)

我想在Vim中找到一个很好的方法来进行此搜索并替换以下内容-

name_1
end
name_2
end

name_3
end

字符串
在这里,我把name_“x”附加到它后面的“end”语句中。所以它看起来像这样-

name_1
end_name_1
name_2
end_name_2
name_3

end_name_3


注意-name_3之前的空行破坏了“name_x”和“end”之间的恒定行间距。

:g/\(name_x\)/,/end/ s/end/end_\1/


这样存储第一个模式是行不通的,但希望你们能理解,有什么窍门吗?
谢谢

bvuwiixz

bvuwiixz1#

您遇到的问题是\1引用的是当前替换的匹配组,而不是:g命令的模式。遗憾的是,您无法从以前的搜索中访问以前的匹配组。然而,有一些方法可以实现您的目标。我建议的第一个方法是宏。
首先从一个不匹配的行开始。如果需要的话,可以在文件的顶部插入一个空行(之后删除它)。
1.开始宏搜索您的模式:/name_\d\+
1.猛拉直到图案结束:y//e
1.查找结束模式:/end/e
1.插入下划线a_
1.粘贴p
1.结束宏q
1.用一个大的数字执行宏.例如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/将在以下行上执行与end匹配的:s
  • s//\=.../匹配最后使用的模式并将其替换为express。
  • submatch(0).'_'.@@创建一个字符串,该字符串具有完整的匹配模式,后跟下划线和未命名寄存器的内容。

有关以下主题的详细信息,请参阅:

:h q
:h search-offset
:h :g
:h :let-@
:h registers
:h matchstr(
:h getline(
:h range
:h submatch(

j5fpnvbx

j5fpnvbx2#

基于正则表达式的解决方案是:

:%s/\(name.*\)\(\n\+.*\)/\1\2_\1

字符串
这个组包含name后跟任何东西的每一行,另一个组可以有任何数量的return后跟任何东西,然后将第一个组附加到第二个组。

相关问题