vim regex只用一个空格replace多个连续的空格

我经常使用文本文件,这些文本文件有不同数量的空格作为单词分隔符(像Word这样的文本处理程序可以完成这项工作,因为某些字体的字母大小不同,所以可以分配相当大的空白量,即使在这种情况下,保存为纯文本)。

我想自动化replace具有单个空格的可变长度的这些空白序列的过程。 我怀疑一个正则expression式可以做到这一点,但也有段落开头(通常是其中四个,但不是总是)的空格,我想让这个空格不变,所以基本上我的正则expression式也不应该触及领先的空格,增加了复杂性。

我使用的是vim,所以如果这是可行的,那么vim正则expression式中的正则expression式对我来说是非常有用的。

我目前的进展如下所示:

:%s/ \+/ /g 

但它不能正常工作。

我也正在考虑编写一个可以parsing文本行的vim脚本,通过char处理每一行字符,并在第一行之后跳过空格,但我有一种感觉,这将是矫枉过正的。

为了实用主义的利益,我倾向于把它作为一个三阶段的过程:

 :g/^ /s//XYZZYPARA/g :g/ \+/s// /g :g/^XYZZYPARA/s// /g 

我不怀疑可能有一个更好的方法(可能使用macros或者甚至是一个纯正则expression式的方式),但是当我匆忙的时候,我通常会发现这个方法是有效的。 当然,如果你有以XYZZYPARA开头的XYZZYPARA ,你可能需要调整string:-)

这是很好的转向:

  This is a new paragraph spanning two lines. And so is this but on one line. 

成:

  This is a new paragraph spanning two lines. And so is this but on one line. 

旁白:如果你想知道为什么我使用:g而不是:s ,那只是习惯。 :g可以做所有事情:s可以,还有更多。 这实际上是一种在选定行上执行任意命令的方法。 在这种情况下执行的命令恰好是s ,所以没有实际的区别,但是,如果你想成为一个vi用户,你应该在某个时刻考虑:g

这将取代2个或更多的空间

 s/ \{2,}/ /g 

或者你可以在你的版本之前添加一个额外的空格

 s/ \+/ /g 

这将做的伎俩:

 %s![^ ]\zs \+! !g 

通过使用\zs\ze元序列,Vim中的许多replace可以比其他正则expression式更容易完成。 他们所做的是从最终结果中排除部分匹配,或者序列之前的部分( \zs ,“s”代表“开始于此”)或者之后的部分( \ze ,“e”代表“结束于此” )。 在这种情况下,模式必须首先匹配一个非空格字符( [^ ] ),但是下面的\zs表示最后的匹配结果(它将被replace) 该字符之后开始。

由于没有办法在行前的空格前面有一个非空格字符,所以不会被模式匹配,所以replace不会替代它。 简单。

这里有很多很好的答案(特别是亚里士多德的: \zs\ze很值得学习)。 只是为了完整性,你也可以用负面的后视断言来做到这一点:

 :%s/\(^ *\)\@<! \{2,}/ /g 

这就是说:“find两个或更多的空格( ' \{2,}' ),这些空格之前没有”行后跟零个或多个空格“。 如果你想减less反斜杠的数量,你也可以这样做:

 :%s/\v(^ *)@<! {2,}/ /g 

但它只能节省你两个字符! 如果您不介意执行冗余更改(即将单个空间更改为单个空间),也可以使用' +'而不是' {2,}'

您也可以使用负面后视来检查单个非空格字符:

 :%s/\S\@<!\s\+/ /g 

这与(为了节省一些input而将亚里士多德的空间和标签作为相同处理的稍微修改过的版本)大致相同:

 :%s/\S\zs \+/ /g 

看到:

 :help \zs :help \ze :help \@<! :help zero-width :help \v 

和(阅读所有!):

 :help pattern.txt 

这是否工作?

 %s/\([^ ]\) */\1 /g 

我喜欢这个版本 – 它类似于亚里士多德Pagaltzis的前瞻版本,但我觉得更容易理解。 (可能只是我不熟悉\ zs)

 s/\([^ ]\) \+/\1 /g 

或所有空白

 s/\(\S\)\s\+/\1 /g 

我把它理解为“用一些东西和一个空格代替空间之外的所有事物”。

回答; 但尽pipe如此,我仍然抛弃了我的工作stream程。

 %s/ / /g @:@:@:@:@:@:@:@:@:@:@:@:(repeat till clean) 

快速和简单的记住。 上面有一个更优雅的解决scheme。 但只是我的.02。