\zs
与前面的正则表达式匹配后“启动突出显示的部分”,而\@<=
与前面的原子匹配后“启动突出显示的部分”。但是我并不完全理解它的微妙之处,所以谁能解释它们在深度上有何不同?这就是让我感到好奇的原因:如果我跑步
/\_s\zsnnoremap
ie选择
nnoremap
前面有一个空格或行的开头(即换行,因此是前一行的换行,因此是\_
之前的s
),然后运行gn
进入可视模式并直观地选择下一个匹配项,由于某种原因,仅第一个匹配项列(即n
中的第一个nnoremap
)被选中-尽管整个nnoremap
单词都在打开:hlsearch
的情况下突出显示。但是,如果我改为运行搜索
/>
/\_s\@<=nnoremap
,然后尝试
gn
,正确选择了整个nnoremap
。这可能是怎么回事?我(敢说)发现了一些晦涩的错误吗?#1 楼
看起来您确实发现了一个晦涩的错误。我早在2012年就为Vim 7.3实现了gn
文本对象。它基本上按以下方式工作:1)向后搜索当前正则表达式的最后一个匹配项。
2)向前搜索该正则表达式的下一个匹配项。当前正则表达式。
这应该使光标清楚,即使在1)的开头已经位于下一个匹配项的开头。最后
3)它搜索当前正则表达式的结尾。并将光标放在此处。
现在发生的是,对当前比赛结束处的搜索回绕并移回到上一个比赛结束处(因为在已禁用1))。然后将Visual标记设置为从起点(点2的终点)到下一个搜索项3所移动到的区域。
我将仔细研究这个问题,并将可能稍后再提交Vim补丁。
[更新22.05.2018]我已经编写并提交了补丁来修复此问题。
[Update2 22.05.2018]
该补丁已合并为补丁级别8.1.0018
[更新22.10.2019]
自Vim补丁8.1.629起,不再执行第三步。现在,Vim现在可以在找到比赛开始时确定比赛结束(第2步)
#2 楼
Christian已经完全解决了gn
的越野车问题,但\zs
和\@<=
之间仍然存在根本差异。正则表达式中最大的一个\@<=
修饰前一个原子,而\zs
是iself中的原子。考虑:匹配列1,那里有一个X。
\%1c
只是使匹配在X后面的位置重新开始。正则表达式2不匹配,因为尽管\zs
与第一列匹配,但\%1c
的宽度为零(如文档中所述),并且X\@<=
从第2列开始。补齐第1列和第2列之间的位置差。正则表达式3匹配,因为
nnoremap
从第2列开始。评论
我不认为正则表达式2会失败,因为没有什么可以弥补第1列和第2列之间的位置差异。如果是这个问题,那么从正则表达式中删除nnoremap会产生匹配;但是即使没有,正则表达式仍然会失败。我认为它失败了,因为\%1cX \ @ <=表示了一个不存在的位置。 \%1c匹配第1列的位置,X \ @ <=要求在此之前匹配字符X。但是第一列之前不能有任何字符。这就是为什么即使用点(任何字符)替换X,正则表达式\%1c。\ @ <=仍然会失败。
–user938271
19-09-4在18:12
#3 楼
\zs
适用于整个正则表达式,并将下一个字符设置为整个匹配的第一个字符。 \zs
之前的任何内容都不会包含在匹配文本中。另一方面,\@<=
仅影响直接在其周围的原子,允许您指定下一个原子仅在以下情况下才匹配它跟随前面的原子。因此,例如,正则表达式:\vbar.*(foo)@<=bar
将匹配
bar
的两个实例(包括实例本身)之间的所有文本,但前提是第二个前面带有foo
。也就是说,它将匹配:barbazfoobar
,但不匹配:
barbazbazbar
,因为
\@<=
以此方式进行了本地化,甚至可以在单个表达式中多次使用\@<=
:\vbar.*(foo)@<=bar.*(foo)@<=bar
以下内容将匹配
bar
的三个实例,但前提是后两个实例均以foo
开头。ie给定文本:
barfoobarbazfoobar
barfoobarbazbazbar
barbazbarbazfoobar
仅与第一行匹配。
评论
但是您可以用\ zs交换后面的第一个后视,也就是说,这也应该起作用:\ vfoo \ zsbar。*(foo)@ <= bar。
– Karl YngveLervåg
18年5月22日在6:48
@KarlYngveLervåg好点。我进行了编辑,以使区别更加清晰,并使用其中无法完全替换\ zs的示例。
–丰富
18年5月22日在8:46
因此,据我了解,\ zs和\ ze可以替换为正则表达式模式,它们更强大,对吗?更强大的功能是,它们可以多次使用,并且可以与\(\)分组。也因为它们像Perl的正则表达式一样工作。有什么事吗
–klaus
19 Mar 20 '19在10:36
@klaus这听起来对我来说是正确的(尽管我不是专家)。请注意,您应该尽可能使用\ zs / \ ze,因为它们比环顾四周快。
–丰富
19年3月29日在9:04
明白了\ zs和\ ze显然更直观。感谢您的解释。
–klaus
19年3月29日在9:24
评论
我认为它是:h模式,但我的记忆表明正则表达式由原子组成,如果这有助于解释差异。