Vim 技巧 - 重用上次的查找模式
将 substitute 命令的查找域留空,意味着 Vim 将会重用上次的查找模式。我们可以利用这一特点精简工作过程。
事实明摆着,为了执行一次 substitute 命令,我们必须要打很多字。首先,指定命令的执行范围;然后,输入查找模式以及替换域的内容;最后,在命令末尾添加合适的标志位。由此可见,我们需要考虑的东西有很多,无论在哪一字段敲错了键,都有可能导致结果出现偏差。
好消息是当我们把查找域留空时,就会让 Vim 使用当前的模式。
看看这个庞大的 substitute 命令吧(技巧 - 利用查找历史,迭代完成复杂的模式):
➾:%s/\v'(([^']|'\w)+)'/“\1”/g
它等价于以下两条单独的命令:
➾ /\v'(([^']|'\w)+)'
➾:%s//“\1”/g
那又怎样?因为不管怎么变,我们还是得输入完整的模式,对吧?但这并不是关键。执行 substitute 命令通常包括两个步骤:一是撰写查找模式,二是设计合适的替换字符串。因此,一分为二的技术让我们消除了这两项任务的耦合性,这才是关键所在。
在我们撰写复杂的正则表达式过程中,通常需要尝试多次才能达到正确的匹配效果。如果打算通过执行 substitute 命令的方式来验证模式的话,每次执行命令都会改变文档的内容,这样做简直太麻烦了。与之形成鲜明对比的是,当执行查找命令时,文档不会被修改。因此,即使我们犯的错误再多也无所谓。总之,将两个任务彻底分开,将使得我们的工作过程更加清晰。正所谓,万事俱备,一举成功。
# 并非永远奏效
我的意思并不是说绝对不能在 substitute 命令的查找域中输入文本。例如,下面的 substitute 命令会把文件中每一行的换行符都替换为逗号,最终形成一行。
➾:%s/\n/,
对于这种简单的命令,就没必要将它一分为二了。否则的话,非但得不到什么好处,反而有可能增加工作量。
# 对命令历史的影响
另外需要注意一点,把查找域留空,会在命令历史中留下一项不完整的记录。由于模式通常保存在 Vim 的查找历史记录中,而 substitute 命令则保存于 Ex 命令的历史记录中(参见:h cmdline-history)。因此,将查找任务与替换任务分离,会致使这两组信息被单独存放,从而导致当你再想重用之前的 substitute 命令时,会遇到困难。
如果你觉得将来会以完整形式来调用历史记录中的 substitute 命令,就要养成在查找域中填充内容的习惯。你只需在命令行中输入<C-r>/
,即可把上次的查找内容粘贴进来。因此,通过以下命令,我们就可以在命令历史中创建一项完整的记录。
➾:%s/<C-r>//“\1”/g
在使用 substitute 命令时将查找域留空,有时很方便,有时却很麻烦。两种方法都体验一下,你就会形成自己的直觉,并依此来判断使用的时机。就像我常说的那样,要靠你自己的判断。