6

假设我有以下代码行:

something:somethingElse:anotherThing:woahYetAnotherThing

我想用除了第一个之外的每个替换:; 这样该行看起来像这样:

something:somethingElse;anotherThing;woahYetAnotherThing

有没有办法在不使用确认每个替换操作:[range]s/[search]/[replace]/[options]的选项的情况下使用命令执行此操作?c

据我所知,s作用的最小范围是单行。如果这是真的,那么完成上述任务的最快方法是什么?

4

4 回答 4

6

我对自己很陌生;我认为您对范围仅是行(不是 100% 确定)是正确的,但是对于这个特定示例,您可以尝试用全局标志替换所有实例,然后通过省略全局标志来放回第一个实例——类似的东西:s/:/;/g|s/;/:/

注意:如果该行在;第一行之前包含 a ,:那么这将不起作用。

于 2012-11-08T23:50:12.553 回答
2

以下是您如何使用单次击键来做您想做的事情(通过映射大写Q):

map Q :s/:/;/g\|:s/;/:<Enter>j

每按一次Q当前行都会被修改,光标会移动到下一行。

换句话说,您可以连续点击Q多次来编辑每一行。

解释:

这将在当前行上全局运行:

:s/:/;/g

这会将第一个分号切换回冒号:

:s/;/:

@AlliedEnvy 的答案将这些组合成一个声明。

我的 map 命令将@AlliedEnvy 的答案分配给大写的 Q 字符。


另一种方法(如果我只需要这样做一次,我可能会这样做):

f:;r;;.

然后您可以反复按;.直到到达行尾。

(您选择替换分号使这有点令人困惑)

解释:

  • f:- 转到第一个冒号
  • ;- 转到下一个冒号(重复在线搜索)
  • r;- 用分号替换当前字符
  • ;- 重复最后一次内联搜索(再次)
  • .- 重复上一条命令(用分号替换当前字符)

长话短说:

  • fxx- 移动到当前行的下一个出现
  • ;重复最后的内联搜索
于 2012-11-08T23:55:27.577 回答
2

干得好...

:%s/\(:.*\):/\1;/|&|&|&|&

这是一个简单的正则表达式替代品,可以处理一个not-the-first :

&命令重复上一次替换。

|语法将多个命令分隔在一行上。因此,每个替代品都会重复多少次|&

于 2012-11-09T00:05:43.977 回答
2

虽然其他答案适用于这种特殊情况,但这里有一个更通用的解决方案:

创建从第二个元素开始到行尾的视觉选择。然后,通过包括以下内容将替换限制在可视区域\%V

:'<,'>s/\%V:/;/g

或者,您可以使用vis.vim 插件

:'<,'>B s/:/;/g
于 2012-11-09T07:29:40.303 回答