如何在Vim中删除多范围内的空行

时间:2010-06-16 09:21:11

标签: vim

我收到了一个文本文件:

<p>...</p>
<pre>
...

...
...
...
</pre>
<p>...</p>
<p>...</p>
<p>...</p>
<pre>

...
...

...
</pre>
<p>...</p>

请注意: [pre] ... [/ pre] 之间有一些空行
我想删除它们 但是,我希望保留那些 [p] ... [/ p]
文本文件变为:

<p>...</p>
<pre>
...
...
...
...
</pre>
<p>...</p>
<p>...</p>
<p>...</p>
<pre>    
...
...    
...
</pre>
<p>...</p>

我使用下面的cmd找到它们:

/<pre>\n\zs\_.\{-}\ze\n<\/pre>

但我不知道下一步该做什么! 我需要 one-line-cmd 才能做到这一点 任何的想法?谢谢!
越简单越好!

<小时/> 修改 谢谢你们。我只是在another question

的帮助下弄清楚如何做到这一点
:g/<pre>/,/<\/pre>/s/^$\n//

3 个答案:

答案 0 :(得分:2)

这个将清除<pre>块中的所有空行:

:%s_<pre>\zs\_.\{-}\ze</pre>_\=substitute(submatch(0), '\n\n\@=', '', 'g')_g

WTF:

:%s_:在缓冲区中的所有行上启动替换命令。您可以在s之后使用任何字符;使用你未在模式中使用的模式(在这种情况下为_)意味着你不必在模式中将其转义。

<pre>\zs\_.\{-}\ze</pre><pre>块内所有字符的最小,多行匹配。

_:从替换

分隔匹配字符串

\=:将此值放在替换的开头表示替换是要评估的vimscript表达式。

substitute(submatch(0), '\n\n\@=', '', 'g')

  • 替换表达式是substitute(...)函数调用。
  • submatch(0):这会给出完整的外部匹配,在这种情况下,\zs\ze之间的所有内容。
  • \n\n\@=:此RE匹配换行符后面的任何换行符,而不会实际超过第二个换行符。 \@=元素称为“零宽度超前断言”; :help /\@会为您提供更多详情。
  • 其余部分非常简单,只需替换换行符即可。请注意,第二个换行符(由前瞻发现的那个)不被视为匹配的一部分,因此不会被替换(至少,直到下一次迭代,它将被替换)如果它后面连续第三个换行符。)

最后,_g只使用g标志关闭表达式,以指示应替换所有实例。我认为助记符是“全球性的”。

答案 1 :(得分:1)

您的问题与公开的there非常相似。

有一个循环(带有搜索,调用“no wrap”)来首先搜索开始标记,然后搜索结束标记。这定义了您将应用g/^\s*$/d_

的范围

向后工作可能更容易,因为有些行会被删除。

编辑:下面的单行似乎也可以正常工作

g/<pre>/,/<\/pre>/s/^\s*$\n//g

答案 2 :(得分:0)

:%s/^$\n//将删除文件中的所有空行。

:%s/\(<pre>\)\(\n\|.\)*\(<\/pre>\)/\1\r\3/会删除<pre></pre>块内的所有内容

这不是你想要的,但它可能有所帮助。