2014-01-15 2 views
14

В Vim есть ли способ поиска строк, которые соответствуют словам abc, но также не содержат xyz позже на линии? Таким образом, следующие строки будут соответствовать:Есть ли способ сделать негативный просмотр в regex vim?

The abc is the best 
The first three letters are abc 

и следующий не будет соответствовать:

The abc is the best but xyz is cheaper 
The first three letters are abc and the last are xyz 

Я знаю о синтаксисе, как следующее:

/abc\(xyz\)\@! 

но только избегает согласования abcxyz и нет, если между ними есть что-то среднее, например abc-xyz. Использование

/abc.*\(xyz\)\@! 

также не работает, потому что есть много позиций, в конце линии, где xyz не соответствует.

(следует отметить, что в командной строке я бы сделать что-то вроде grep abc <infile | grep -v xyz, но я хотел бы сделать выше в интерактивном режиме в Vim.)

ответ

21

Ваша попытка была довольно близко ; вам нужно тянуть .*, что позволяет произвольное расстояние между матчем и утверждаемым позже неигровыми в отрицательные прогнозные:

/abc\(.*xyz\)\@! 

Я предполагаю, что это работает, потому что неигровая попытка для всех возможных совпадений .*, и только когда все ветви были исчерпаны, объявленный \@! считается выполненным.

+1

Это эквивалентно 'аЬс (?!. * Хуг)' в Perl-подобных системах. – nhahtdh

+0

И это работает, потому что простой взгляд запускает еще один полномасштабный поиск из текущей позиции для шаблона и использует результат, чтобы решить, продолжать или нет (в зависимости от того, является ли прогноз вперед положительным или отрицательным). – nhahtdh

+1

также см. ': Help perl-patterns'. Для 'pattern2', которому не предшествует' pattern1', это отрицательный look-behind, ищите '\ (pattern1 \) \ @ hochl

0

Я думаю, что я пишу это, как /abc\(\(xyz\)\@!.\)*$

Я не уверен, является ли это быстрее, чем другие предложения (я думаю, что это может быть, так как он проверяет каждую позицию только один раз), но это концептуальный смысл как:

«а следует всему, что не является хугом, любое количество раз до конца строки»

Мне нравится, что лучше, чем «Азбуки следует ничего не следует а», как и в других моделях, упомянутых.

1

Хотя ваш вопрос касается взгляда, я нашел его во время поиска lookbehind. Таким образом, я отправляю решение искать, чтобы другие могли его найти.

Если вы ищете pattern2 не предшествуют pattern1, что является отрицательным просмотром назад, поиск:

\(pattern1\)\@<!pattern2 
Смежные вопросы