为什么在这种情况下,vim 会在 \ze 之后使用模式?



仅供参考,这个问题源于这个sed答案。

给定一个 5 列 CSV 行,所有 5 列均为空,即仅包含,,,,的行,我认为以下vim-ex命令应该在所有 5 个位置插入hello

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

但是它没有,因为输出是

hello,,hello,hello,hello

插入第一个hello是因为^ze,行首匹配。但是,该命令似乎使用此,。是这样吗?如果是这样,为什么?

我不确定答案,但我可以分享一种预感。 我认为这归结为完全零宽度的匹配/替换模式(例如/^ze,(必须移动一些空灵的匹配指数,即使它在技术上没有消耗任何东西。 这样它仍然可以进入下一场比赛,否则它将保持在同一位置匹配(如果这有意义的话(。

你的例子似乎证明了这一点。 下面是一个更具说明性的示例(更改输入以更好地显示匹配的内容(。

给定以下命令:

:s/v(^|.)ze(.|$)/<01122>/g

针对abcd的输入行运行它将输出:

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

请注意a如何匹配/替换(以<01a2>为单位(,并且也不匹配,如<01a2>a<0b1c2>中的a所示。 这可以防止ab对被匹配/替换。

我唯一能想到的可以解释这一点的是,在与第一个零宽度模式匹配后,某些匹配光标或匹配索引必须经过a的第一个字符/^ze.

换句话说:

Input: abcd
Command: s/v(^|.)ze(.|$)/<01122>/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 ...

相关内容

最新更新