我有这个问题:
输入文字:
this is my text text text and more text
this is my text myspace this is my text
this space is my text space this is my
this is my text this is my text
this space is my text space space myspace
我想说要搜索“空间”
我希望将此作为输出:
this is my text text text and more text
space
space space
this is my text this is my text
space space space space
同一行上的匹配必须用空格分隔 没有匹配的行必须保持原样。
所有其他搜索项目相同。
我正在努力实现这一点,今天下午却没有成功 任何人都可以帮助我吗?
答案 0 :(得分:3)
这个棘手的问题对你好吗?
:g/space/s/space/^G/g|s/[^^G]//g|s/^G/space /g
您需要的^G
按Ctrl-V Ctrl-G
上面命令的输出与你的例子相同除了模式之后的结尾空格(在这种情况下是空格)。但很容易修复,例如在s/ $//
行之后链接另一个:g
。
答案 1 :(得分:3)
:g/space/s/\(.*space\).*$/\1/|s/.\{-}space/ space/g|s/^ //
这很棘手,但可以做到。但是,使用单个正则表达式无法完成。
我们做的第一件事是在最后一场比赛之后摆脱任何事情(我们实际上利用了默认情况下正则表达式贪婪的事实):
s/\(.*space\).*$/\1/
然后我们会删除所有内部匹配项之间的任何内容(请注意,我们在此使用*
的惰性版本,\{-}
):
s/.\{-}space/ space/g
上一步将在结果中留下一个初始空格,所以我们摆脱了:
s/^ //
幸运的是,在vim中,我们可以将替换与|
字符链接在一起。所以,把它们放在一起:
:g/space/s/\(.*space\).*$/\1/|s/.\{-}space/ space/g|s/^ //
答案 2 :(得分:0)
Kent的解决方案使用了一个很好的技巧,使其仅适用于固定字符串,但它干净而且简短。 Ethan Brown的答案更为通用,但它的三个步骤也增加了复杂性。我认为最好的解决方案可以基于the accepted answer in this very similar question开发。
与Ethan Brown假设的情况相反,这确实可以通过单个正则表达式替换来完成。这就是它的丑陋:
:g/space/s/\%(^\|\%(space \)*space\%( \%(.*space\)\@=\)\?\)\zs\%(\%(space \)*space\%( \%(.*space\)\@=\)\?\)\@!.\{-1,}\ze\%(\%(space \)*space\%( \%(.*space\)\@=\)\?\|$\)//g
当您使用PatternsOnText plugin中的:DeleteExcept
命令时,它会变得更具可读性:
:g/space/DeleteExcept/\%(space \)*space\%( \%(.*space\)\@=\)\?/
删除除
之外的所有内容\%(space \)*
space
\%(.*space\)\@=
以便不吞噬空格\?
。虽然提出上述解决方案是一个很好的挑战,但在实践中,我也赞成采用两步法,因为它更简单:
:g/space/DeleteExcept/space\%( \|$\)/
这留下了可以用
修剪的尾随空格:%s/ $//