Есть ли способ сделать негативный просмотр в regex vim?
В Vim существует ли способ поиска строк, которые соответствуют say abc
, но также не содержат xyz
позже в строке? Таким образом, следующие строки будут соответствовать:
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.)
Ответы
Ответ 1
Ваша попытка была довольно близка; вам нужно вытащить .*
, что позволяет произвольное расстояние между совпадением и подтвержденным более поздним несоответствием на негативный прогноз вперед:
/abc\(.*xyz\)\@!
Я думаю, это работает, потому что не-совпадение выполняется для всех возможных совпадений .*
, и только когда все ветки были исчерпаны, объявлен как \@!
.
Ответ 2
Это работает для меня /abc\(.*xyz\)\@!
Ответ 3
Хотя ваш вопрос касается взгляда, я нашел его при поиске lookbehind. Таким образом, я отправляю решение для поиска, чтобы другие могли его найти.
Если вы ищете pattern2
, которому не предшествует pattern1
, это отрицательный lookbehind, выполните поиск:
\(pattern1\)\@<!pattern2
Ответ 4
Думаю, я напишу это как /abc\(\(xyz\)\@!.\)*$
Я не уверен, что это быстрее, чем другие предложения (я думаю, это может быть, так как он проверяет каждую позицию только один раз), но это делает концептуальный смысл следующим:
"abc, за которым следует любое, что не является xyz, любое количество раз до конца строки
Мне нравится это лучше, чем "abc, за которым следует все, за чем не следует xyz", как в других упомянутых шаблонах.