我想了解vim中环顾四周的行为,因此尝试标记断言的位置。假设我有此文件的内容:


foob​​ar


通过执行此命令:s/\(foo\)\@<!/♠ /g我得到了:


♠f♠o♠ob♠a♠r


为什么我在行尾没有?在这种情况下,$锚是否不视为位置?

相反,如果我执行此命令:%s/\(bar\)\@<=/♠ /g,则会得到:


foob​​ar♠


有什么解释吗?有人可以确认这种行为吗?



Vim 7.4 Ubuntu 16.04 LTS

最佳答案

在这两种情况下,您实际上都不匹配任何内容,而只是对此进行断言。

:s/\(foo\)\@<!/♠ /g的行为与更简单的:s/\zs/♠ /g一致

♠ f♠ o♠ o♠ b♠ a♠ r


匹配仅从现有角色开始;每行之后的隐式换行符不计算在内(根据Vim的实现)。



使用第二个:%s/\(bar\)\@<=/♠ /g命令,该断言实际上像简单的$原子一样起作用。因此,与:s/$/♠ /g一样,它会在断言匹配之后插入,即使它后面只有(隐式)尾随换行符也是如此。



因此,尽管可能令人惊讶且与其他正则表达式引擎不一致,但您会发现在Vim内部,这完全与其正则表达式引擎和缓冲区表示的内部工作方式一致。因此,我认为这不是错误。如果您仍然对此感到强烈,可以在bug tracker上提出问题,或直接在vim_dev mailing list上进行讨论。

09-27 16:53