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

时间:2009-09-21 18:30:14

标签: regex vim

我有一个大约1000行的文件。除偶尔的行外,所有行都以七位数开头。我需要抓住这些线并实际将它们与前一行连接起来。

我已经设法通过使用以下正则表达式模式匹配任何以七位数字开头的行:

^\d\{7}

我似乎无法匹配任何不符合此模式的行,但这正是我所追求的。

作为第二个问题,我将把它嵌入到这个问题中。是否有可能匹配(或不匹配以保持与我正在尝试的一致)的任何行将自己连接到前一行(而不是带来的 J 命令下一行到现在的那个?)

由于

4 个答案:

答案 0 :(得分:32)

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

这是vim用于否定前瞻的正则表达式语法。

如果您将此作为群发:命令执行,则应该能够执行此操作

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

答案 1 :(得分:9)

现在,获得真正的答案

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

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

没有{}语法的更经典的正则表达式实际上更具可读性:它直观地向我们展示了正在发生的事情:

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

即。匹配0到6个字符,可以是任何字符,可选地后跟非数字,如果它出现,可以跟随零个或多个附加字符。这可以确保如果匹配七个字符或更长字符串的字符串,则前七个字符中至少有一个是非数字字符。

要将其转换为Vim中的匹配行,我们添加一些转义和锚定:

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

我不做"做" \d;它过于新颖了。 :)

答案 2 :(得分:7)

正则表达式

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

将反转您的原始表达。有关此语法的详细信息,请参阅此处:

:help \@!

至于第二个问题,你可以用例如替换前一行的尾随换行符:

:%s/$\n^\(\d\{7}\)\@!//g

答案 3 :(得分: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