我想在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/
型
这样存储第一个模式是行不通的,但希望你们能理解,有什么窍门吗?
谢谢
2条答案
按热度按时间bvuwiixz1#
您遇到的问题是
\1
引用的是当前替换的匹配组,而不是:g
命令的模式。遗憾的是,您无法从以前的搜索中访问以前的匹配组。然而,有一些方法可以实现您的目标。我建议的第一个方法是宏。首先从一个不匹配的行开始。如果需要的话,可以在文件的顶部插入一个空行(之后删除它)。
1.开始宏搜索您的模式:
/name_\d\+
1.猛拉直到图案结束:
y//e
1.查找结束模式:
/end/e
1.插入下划线
a_
1.粘贴
p
1.结束宏
q
1.用一个大的数字执行宏.例如
999@q
下面是我使用的宏:
字符串
另一种方法是使用
:global
命令,其方式与您的尝试类似。型
我个人这是太复杂了,但它是很好的选项.该命令可以分为以下几部分:
:g/name_\d\+
在每一行上执行一个命令,匹配name_和某个数字getline('.')
将返回当前行的字符串matchstr(getline('.'), 'name_\d\+')
将只返回当前行的匹配部分let @@ = matchstr(...)
将匹配部分设置为默认寄存器/end/s/
将在以下行上执行与end
匹配的:s
s//\=.../
匹配最后使用的模式并将其替换为express。submatch(0).'_'.@@
创建一个字符串,该字符串具有完整的匹配模式,后跟下划线和未命名寄存器的内容。有关以下主题的详细信息,请参阅:
型
j5fpnvbx2#
基于正则表达式的解决方案是:
字符串
这个组包含
name
后跟任何东西的每一行,另一个组可以有任何数量的return
后跟任何东西,然后将第一个组附加到第二个组。