Как мне заставить Vim соответствовать строке, не начинающейся с семизначного числа? - PullRequest
26 голосов
/ 21 сентября 2009

У меня есть файл с около 1000 строк. Все строки начинаются с семизначного числа, за исключением случайной строки. Мне нужно поймать эти строки и соединить их с предыдущей строкой.

Мне удалось сопоставить любую строку, начинающуюся с семизначного числа, с помощью следующего шаблона регулярных выражений:

^\d\{7}

Я не могу заставить его совпадать с любой строкой, которая не соответствует этому шаблону, хотя это действительно то, что я ищу.

Как второй вопрос, который я вставлю в этот. Возможно ли иметь какие-либо строки, которые соответствуют (или не совпадают, чтобы соответствовать тому, что я пытаюсь сделать), чтобы присоединиться к предыдущей строке (в отличие от команды J , которая приводит к до текущей)?

Спасибо

Ответы [ 4 ]

32 голосов
/ 21 сентября 2009
^\(\d\{7}\)\@!

Это синтаксис регулярных выражений vim для отрицательного взгляда.

Если вы делаете это как массовую : команду, вы можете просто выполнить

:v/^\d\{7}/-1j
9 голосов
/ 09 апреля 2012

Теперь, для реального ответа

Регулярное выражение, которое соответствует строкам, которые не начинаются с 7 цифр, очень просто:

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

Более классический эквивалент регулярного выражения без {} синтаксиса на самом деле более читабелен: он наглядно показывает нам, что происходит:

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

т.е. совпадение от 0 до 6 символов, которое может быть чем угодно, за которым может следовать нецифровое число, за которым, если это происходит, может следовать ноль или более дополнительных символов. Это гарантирует, что при совпадении строки из семи или более символов по крайней мере один из первых семи символов будет недисцифрованным.

Чтобы перевести это на соответствующие строки в Vim, мы добавили некоторые экранирование и привязку:

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

Я не "делаю" \d; это слишком модно. :)

7 голосов
/ 21 сентября 2009

регулярное выражение

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

инвертирует ваше исходное выражение. Для получения дополнительной информации об этом синтаксисе см. Здесь:

:help \@!

Что касается второй проблемы, вы можете, например, заменить завершающий символ новой строки на предыдущих строках ничем:

:%s/$\n^\(\d\{7}\)\@!//g
1 голос
/ 22 сентября 2009

Вот мое решение с использованием 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...