Область синтаксиса Vim - путаница назад

Определите следующее в .vimrc или выполните в командной строке vim:

syn match ndbMethods "[^. \t\n\r]\@<=[_a-z][_a-zA-Z0-9]*(\@="
hi ndbMethods guibg=#222222

Просмотрите результаты с помощью вызова метода в стиле C в активном буфере:

foo();

Вы увидите, что начальный символ имени метода не совпадает.

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

Как ни странно, использование отрицательного прогноза (\@<!), похоже, работает!

Будет ли кто-нибудь достаточно любезен, чтобы объяснить, почему этот взгляд назад неверен?


person KomodoDave    schedule 27.08.2012    source источник
comment
В vim есть одна довольно странная функция: [^\n] будет соответствовать любому символу , включая новую строку. [\n] внутри коллекций всегда добавляет новую строку к совпадению, независимо от того, есть ли у вас ^ в начале или нет. Во избежание путаницы всегда используйте вариант \_[], который эквивалентен [\n].   -  person ZyX    schedule 27.08.2012


Ответы (1)


Обновлено: На странице f, глядя назад, вы, вероятно, захотите проверить [. \t\n\r], а не [^. \t\n\r]. Потому что в настоящее время вы говорите «что-то, что не следует за одним из этих символов», поэтому это условие выполняется только при достижении o, поскольку f действительно не является одним из этих символов. Таким образом, вам нужно либо отменить отрицание класса символа, либо, как вы обнаружили, отменить обратный просмотр.

Я думаю, вы тоже путаете свои термины.

\@<=    positive lookbehind
\@<!    negative lookbehind
\@=     positive lookahead
\@!     negative lookahead
person slackwing    schedule 27.08.2012
comment
О боже, я намерен [^. \ t \ n \ r] смотреть назад! Разве \ @ ‹= не применяется к предыдущему шаблону так же, как \ @ =? См. Примеры здесь, например: ssiaf.blogspot.co. uk / 2009/07 / negative-lookbehind-in-vim.html. Взгляд назад, который он использует, безусловно, эквивалентен моему, за исключением того, что у меня есть класс символов, содержащий '.' и т. д. вместо его (Старт) - person KomodoDave; 27.08.2012
comment
Ах, это моя проблема - я поставил '^' в начале своего набора символов! Он предназначен для соответствия началу строки, поэтому должен быть не в начальной позиции в этом наборе символов. Переход на [. \ t \ n \ r ^] исправляет это. Искренне спасибо за ваш пост :-) - person KomodoDave; 27.08.2012
comment
Я споткнулся по пути, но рад помочь. - person slackwing; 27.08.2012
comment
@ acheong87 Не забывайте, [^. \t\n\r] соответствует любому символу, кроме точки, пробела, табуляции или возврата каретки, включая новую строку. См. :h /[\n]. - person ZyX; 27.08.2012
comment
@KomodoDave ^ внутри коллекции никогда не будет соответствовать началу строки. Он либо отменит коллекцию (кроме \n), либо совпадет с литералом ^. Лучше записывать его как \%(^\|[. \t]\)\@<=, поскольку \r обычно не должен появляться в тексте (если у вас есть окончания строк dos и вы отредактируете его с правильным форматом файла, \r\n будет сведен в однострочный разделитель, и \r никогда не будет совпадать), а \n не будет совпадать в начало первой строки. - person ZyX; 27.08.2012
comment
@ZyX Спасибо за эти исправления, в радости, обнаружив ошибку "^", я сделал еще одну! Я не был уверен насчет \\ r, поэтому ценю ваше разъяснение. Почему (^ \ | [. \ T]) недостаточно? Я вижу 3 примера в: he / atom, это \ (, \\% (, \\ z (. Я бы выбрал \ (и выделение синтаксиса примечаний с помощью \\ z (и не упоминайте \ \% (, поэтому был бы признателен за разъяснения. - person KomodoDave; 27.08.2012
comment
(Игнорируйте двойные escape-последовательности в приведенном выше примере, они были предназначены как одиночные, чтобы преодолеть форматирование комментариев SO) - person KomodoDave; 27.08.2012
comment
Я пошел на это: \ (^ \ | [. \ T \ n \ r] \) \ @ ‹= вроде работает нормально. Дайте мне знать об этом%, если у вас будет возможность! - person KomodoDave; 27.08.2012
comment
@KomodoDave В основном \%(\) - это небольшая и почти всегда несущественная оптимизация: \(\) - это группа захвата, которая заставляет vim запоминать значение согласованной части. \%(\) - это не захватывающая группа, она спасает некоторые тики, не заставляя vim делать это. Для длинных шаблонов с большим количеством групп захвата, которые необходимо захватить, это единственный способ записать те, которые этого не делают: количество \(\) ограничено девятью группами. Для меня это просто стиль письма: мне не нужна группа для захвата - я пишу %, чтобы указать на это. Все объяснено на :h /\%(. - person ZyX; 28.08.2012
comment
@KomodoDave И используйте обратные кавычки, чтобы заключить фрагменты кода (в данном случае - регулярное выражение), вам не нужно в этом случае использовать двойную обратную косую черту. - person ZyX; 28.08.2012
comment
@ZyX Спасибо за то, что нашли время объяснить, очень интересно узнать такие идеи. В конце концов, регулярные выражения бесценны для любого пользователя vim! И обратная кавычка приветствуется, я буду следовать вашему совету в будущем. - person KomodoDave; 28.08.2012