仅供参考,这个问题源于这个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 ...