温馨提示:本文翻译自stackoverflow.com,查看原文请点击:regex - Why does vim consume the pattern after \ze in this case?
regex regex-lookarounds vim

regex - 在这种情况下,为什么vim占用\ ze之后的模式?

发布于 2020-04-13 12:16:43

费,这个问题源自这个sed答案

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

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

但是不是,因为输出是

hello,,hello,hello,hello

hello插入第一个是因为^\ze,匹配在行的开头。但是,这似乎,被命令消耗了。是这样吗 如果是这样,为什么?

查看更多

提问者
Enrico Maria De Angelis
被浏览
64
alvinfrancis 2020-02-04 18:41

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

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

给出以下命令:

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

在输入行上运行它将abcd输出:

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

注意如何a既匹配/替换(在<01a2>),并且也无法比拟的如由a<01a2>a<0b1c2>这样可以防止ab配对/替换。

我唯一能想到的是,这可以解释为某些匹配游标或匹配索引必须先a被的第一个零宽度模式匹配后才移过第一个字符/^\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 ...