Я не уверен в ответе, но могу поделиться догадкой. Я думаю, что это сводится к тому, что шаблоны совпадения / замены с нулевой шириной (например, /^\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 ...