Почему в этом случае vim использует шаблон после \ ze? - PullRequest
4 голосов
/ 03 февраля 2020

К вашему сведению, этот вопрос возник из этого sed ответа .

С учетом строки CSV из 5 столбцов с пустыми всеми 5 столбцами, т.е. строки, которая содержит только ,,,,, I думал, что следующая команда vim - ex должна вставить hello во все 5 позиций:

:s/\v(^|,)\ze(,|$)/\1hello/g

Однако это не так, так как вывод

hello,,hello,hello,hello

Первый hello вставлено, потому что ^\ze, совпадает в начале строки. Однако, похоже, что , используется командой. Это тот случай? Если так, то почему?

1 Ответ

1 голос
/ 04 февраля 2020

Я не уверен в ответе, но могу поделиться догадкой. Я думаю, что это сводится к тому, что шаблоны совпадения / замены с нулевой шириной (например, /^\ze,) вынуждены перемещать некоторый эфирный индекс совпадения на единицу, даже если технически он ничего не потребляет. Таким образом, он все еще может go к следующему совпадению, иначе он просто продолжит сопоставление в той же позиции (если это имеет смысл).

Ваш пример, кажется, подтверждает это. Более наглядным примером будет следующий (изменение ввода для лучшего отображения того, что было сопоставлено).

С учетом следующей команды:

:s/\v(^|.)\ze(.|$)/<0\11\22>/g

Запуск его для строки ввода abcd выведет:

<01a2>a<0b1c2><0c1d2><0d12>

Обратите внимание, что a соответствует или заменяется (в <01a2>), а также не соответствует , как показано a в <01a2>a<0b1c2>. Это предотвращает сопоставление / замену пары ab.

Единственное, что я могу придумать, это объясняет это тем, что некоторый курсор или индекс совпадения должны перемещаться за первый символ * 1022. * после сопоставления с первым шаблоном нулевой ширины /^\ze.

Другими словами:

Input: abcd
Command: s/\v(^|.)\ze(.|$)/<0\11\22>/g
======================================

Match/Replace 1:
abcd => <01a2>abcd
^              ^

Matches /^ze.
Will move cursor by 1 after the zero-width /^\ze. match (or else it would be stuck there)

----------------

Match/Replace 2:
<01a2>abcd  =>  <01a2>a<0b1c2>cd
       ^                      ^

Matches /.\ze.
Consumes the '.' (in this case 'b').  Not entirely zero-width.

... and so on ...
...