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

如何在Vim中删除多个范围内的空行,vim,Vim,我得到一个文本文件: <p>...</p> <pre> ... ... ... ... </pre> <p>...</p> <p>...</p> <p>...</p> <pre> ... ... ... </pre> <p>...</p> :g/<pre>/,/<\/pre>/s/^$\n//

我得到一个文本文件:

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

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

...
...

...
</pre>
<p>...</p>
:g/<pre>/,/<\/pre>/s/^$\n//

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

... ... ...

请注意:在[pre]…[/pre]之间有一些空行
我想删除它们。
但是,我想把它们保存在[p]…[/p]
文本文件变为:

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

... ... ...

我使用下面的cmd来定位它们:

/\n\zs\\.{-}\ze\n
但我不知道下一步该怎么办
我需要一个单行命令来执行此操作。
有什么想法吗?谢谢
越简单越好

编辑: 谢谢大家。我只是在我的朋友的帮助下想出了怎么做

:g//,//s//^$\n//

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

:%s/\(\)\(\n\\.\)*\(\)/\1\r\3/
将删除
块内的所有内容


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

你的问题与暴露的问题非常相似

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

由于某些行将被删除,向后操作可能更容易

编辑:下面的一行代码似乎也很有效

g//,//s//^\s*$\n//g

此选项将清除
块中的所有空行:
块中所有字符的最小多行匹配

\
:从替换中划界匹配字符串

\=
:将其放在替换的开头表示替换是要计算的vimscript表达式

替换(子匹配(0),'\n\n\@=',''g')

  • 替换表达式是一个
    substitute(…)
    函数调用
  • 子匹配(0)
    :这提供了完整的外部匹配,在本例中,是
    \zs
    \ze
    之间的所有匹配
  • \n\n\@=
    :这将重新匹配紧跟新行的任何新行,而不会实际超过第二个新行。
    \@=
    元素称为“零宽度前瞻断言”<代码>:help/\@将为您提供更多详细信息
  • 其余部分相当简单,只需将所有出现的换行符替换为零即可。请注意,第二个换行符(由前面的换行符发现的换行符)不被视为匹配的一部分,因此不会被替换(至少要等到下一次迭代时,如果它后面有第三个连续的换行符,就会被替换)

最后,
\u g
只是用一个
g
标志关闭表达式,以指示应替换所有实例。我认为助记符是“全局的”。

您已经删除了所有空行。如果我想把这些放在…?@键之外,我添加了另一个命令,它可以做一些有趣的事情。不过,我不确定这在一行中是否可行。谢谢。我只是想知道怎么做:g//,///s//^$\n//@Kev:请使用``转义使代码段可读。你的
:g//,//s//
现在几乎难以辨认(
\//
看起来像
V
,例如)。我认为
g/../s/../g
如果有一行匹配的
*
使用vimscript替换表达式应该得到+1