如何让Vim匹配不以七位数字开头的行?

28

我有一个文件,大约有1000行。除了偶尔的几行之外,所有行都以七位数开头。我需要捕获这些行并将它们与前一行合并。

我已经成功使用以下正则表达式模式匹配所有以七位数字开头的行:

^\d\{7}

我似乎无法使它匹配任何不符合这种模式的行,然而这确实是我想要的。

作为一个嵌入到这个问题中的第二个问题。是否有可能使任何匹配的行(或者不匹配以保持与我所试图做的事情一致)与前一行连接在一起(而不是使用J命令将下一行带到当前行)?

谢谢

4个回答

38
^\(\d\{7}\)\@!

这是Vim用于负向先行断言的正则表达式语法。

如果你想将其作为批量:命令来执行,你应该只需执行:

:v/^\d\{7}/-1j

很奇怪,它们都导致了同样的结果。虽然对我来说,没有 ^ 的那个实际上能工作,但现在想想也不太合理。 - Jason Down
唯一的区别是没有 ^ 的那个将匹配行中除开头以外其他位置出现的七位数字。 - chaos
啊,我明白了。在这种情况下没有额外的行被修改,这就解释了为什么较少行的计数完全相同。 - Jason Down
如果我想搜索不以<a href开头的行,我会尝试使用以下命令:/^\(<a href\)\+\@!。但是,我会收到以下错误提示:E871: (NFA regexp) Can't have a multi follow a multi ! - Olivier Pons
使用\v会简化事情并使其更像PCRE语法:\v^(\d{7})@! - jdhao
显示剩余4条评论

9

现在,为了真正的答案

匹配不以7个数字开头的字符串的正则表达式非常简单:

.{0,6}([^0-9].*)?

没有使用 {} 语法的经典正则表达式实际上更易读:它可以直观地展示我们正在进行的操作:

(|.|..|...|....|.....|......)([^0-9].*)?

即匹配0到6个任意字符,可选跟着一个非数字字符,如果存在的话,可以跟着零个或多个额外的字符。这确保了如果匹配了七个或更长的字符串,则前七个字符中至少有一个是非数字。

要将其翻译成在Vim中匹配行的格式,我们需要添加一些转义和定位符:

^.\{0,6\}\([^0-9].*\)\?$

我不会使用“\d”,它太新潮了。 :)

顺便说一下,当我写下最后一行并提交了这个月的内容时,我双手交叉。这是提交记录链接:http://www.kylheku.com/cgit/txr/commit/?id=e63c7be49e144d2ed3967c28243109342e17dcaa - Kaz

8
正则表达式
^\(\d\{7}\)\@!

将反转您的原始表达式。有关此语法的更多信息,请参见此处:

:help \@!

对于第二个问题,您可以例如去掉前面行的尾随换行符:
:%s/$\n^\(\d\{7}\)\@!//g

这个很接近了,但是另一个答案中的连接在连接在一起的行之间留下了一个空格(这实际上是我需要的)。这个例子将第一行的最后一个字符直接放在下一行的第一个字符之前。这是一个副作用,我需要避免。不过,还是给你点赞并感谢你的回答。 - Jason Down
哦,好吧!不过可以这样添加空格::%s/$\n^\(\d{7}\)@!/ /g - tobiasvl
足够正确。不过另一个更短,而且我有点懒 ;P - Jason Down

1

这是我的解决方案,使用 awk 编写,可以在 vim 中调用:

$ cat seven.awk
# Script to join lines that does not start with 7 digits
/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ { print; next }
{ printf $0; getline; print }

$ cat seven.txt
123
4579 bad
7654321 This line is OK
1234567 OK So is this
111
2222 bad again
4443333 OK again

$ awk -f seven.awk seven.txt
1234579 bad
7654321 This line is OK
1234567 OK So is this
1112222 bad again
4443333 OK again

请原谅我的笨拙表达:我的awk版本较老,无法理解像\d{7}这样的高级表达式。如果您想在vim中为整个文件调用此命令,请执行以下操作:
:%!awk -f seven.awk

我最初也有[0-9]七次。我很高兴gVim中的ex编辑器允许\d{7}快捷方式。 - Jason Down

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接