Как найти третье вхождение шаблона в строку

Сегодня мне пришлось выровнять таблицу только по первым нескольким пробелам в строке.

p.e.

<ScrollWheelDown>    move window     three lines     down  
<S-ScrollWheelDown>     move window    one page   down
<ScrollWheelUp>        move window      three lines up
<S-ScrollWheelUp>    move window   one page      up

Я использую плагин Tabular для выравнивания таблиц, но я не смог найти способ найти только первое вхождение нескольких пробелов и выполнить выравнивание только там.

Я не знаю этого и в VIM: каким будет регулярное выражение, если я хочу найти только 3-е вхождение шаблона в строке? Является ли регулярное выражение таким же, как использование Tabular?


person Reman    schedule 24.03.2011    source источник


Ответы (4)


Регулярное выражение будет:

/\(.\{-}\zsPATTERN\)\{3}

Итак, если, например, вы хотите изменить 3-й «foo» на «bar» в следующей строке:

lorem ifoopsum foo lor foor ipsum foo dolor foo
       ^1      ^2      ^3         ^4        ^5

бегать:

s/\(.\{-}\zsfoo\)\{3}/bar/

получить:

lorem ifoopsum foo lor barr ipsum foo dolor foo
       ^1      ^2      ^3=bar     ^4        ^5
person Eelvex    schedule 24.03.2011
comment
Очень хорошее использование \zs внутри блока \(...\). Не знал, что при повторении зз учитывался только последний. Конечно, :help /\zs утверждает это. - person Benoit; 25.03.2011
comment
Спасибо, Eelvex, у меня все еще есть небольшая проблема. Регулярное выражение не останавливается после того, как оно нашло 3-й «foo». Это также изменит 6-й «foo» и 9-й «foo». Как я могу остановить регулярное выражение после третьего «foo»? - person Reman; 25.03.2011
comment
@Remonn: Просто запросите начало строки (^) в начале: /^\(.\{-}..., но действительно ли это необходимо? :s без g в конце заменит только первое вхождение вашего третьего шаблона. :) - person Eelvex; 25.03.2011
comment
Это было довольно просто. Спасибо. - person Reman; 25.03.2011
comment
Альтернативным синтаксисом, использующим модификатор \v, является s/\v(.{-}\zsfoo){3}/bar/, который может предлагать или не предлагать улучшенную читабельность, в зависимости от ваших предпочтений между обычным экранированием и \v. - person airstrike; 25.06.2014
comment
следует добавить ^ в самое начало регулярного выражения ( ^\(.\{-}\zsPATTERN\)\{3} ), иначе будет совпадать каждый 3-й ШАБЛОН (т.е.: 3-й, 6-й, 9-й,...). подробности: marslo.github.io/ibook/vim/ ricky.html#matches-the-n-pattern - person Marslo; 24.06.2021

Я не знаю, соответствует ли это вашим потребностям, но вы можете искать таким образом:

  1. Поместите курсор в начальную строку
  2. Введите 3 / pattern Возврат

Он помещает курсор на 3-е вхождение следующей совпадающей строки (выделяя все вхождения)

Вы также можете использовать макрос:

qa+3nq

затем @a для перехода к следующей строке 3-е вхождение

person M'vy    schedule 24.03.2011
comment
не совсем потому, что он ищет только в одной строке 3-е вхождение, а в других строках - первое вхождение. - person Reman; 24.03.2011
comment
Вы также можете прыгать 3 на 3 с помощью ‹kbd›3‹/kbd› ‹kbd›n‹/kbd›. - person M'vy; 24.03.2011
comment
Возможно, с помощью макроса вы сможете упростить процесс. Я полагаю, что есть также ярлык для перехода к началу следующей строки, но не помню его. - person M'vy; 24.03.2011
comment
(См. также Как работают комментарии @ответы?) - person Arjan; 25.03.2011

Для пользователей Google (таких как я), которые ищут только «регулярное выражение n-го вхождения». Это вернет позицию последнего символа третьего «foo» (вам нужно изменить {3} на ваш n и foo на ваш текст):

length(regexp_replace('lorem ifoopsum foo lor foor1 ipsum foo dolor foo', '((?:.*?foo){3}).*$', '\1'))

Это: (?:.*?foo) ищет все, за чем следует 'foo', затем повторяется 3 раза (?:.*?foo){3}, затем захватывается строка от начала до (включая) 3-го повторения, затем остальная часть строки сопоставляется с .*$, затем вся строка заменяется захваченной вещью , а его длина - это позиция последнего символа 3-го «foo».

person alexkovelsky    schedule 02.05.2015
comment
P.S. эти регулярные выражения 'vim', какими бы они ни были, выглядят ужасно. - person alexkovelsky; 02.05.2015

Попробуй это:

:Tabularize /^.\{-}\S\s\{2,}

Да, Tabularize использует регулярное выражение Vim, поэтому пример ответа Eelvex должен работать.

person Raimondi    schedule 24.03.2011
comment
таблично 2-й ,, он должен быть :Tabularize /^\(.\{-}\zs,\)\{2}/l1l0 ; или с \v: :Tabularize /\v^(.{-}\zs,){2}/l1l0. подробности: marslo.github.io/ibook/ вим/ ; и marslo.github.io/ibook/vim/tricky .html#matches-the-n-pattern - person Marslo; 24.06.2021