假设我想替换在两个初始a
s之后的所有a
s,并且在它和前两个a
s之间只有a
s。我可以在Vim中使用(非常神奇的v
(regexs:v(^a{2}a{-})@<=a:X:g
:来执行此操作
aaaaaaaaaaa
转到
aaXXXXXXXXX
但是,为什么s:v^a{2}a{-}zsa:X:g
只替换第一次出现的内容?即,给出
aaXaaaaaaaa
我想这是因为第一场比赛";消耗";该行的开始和前2个a
s,使得以后的匹配仅在该行的剩余部分上匹配,该剩余部分再也不能匹配^
。这是真的吗?或者更确切地说,最具教学意义的解释是什么?
第页。这是另一个问题的一个极小的例子。
编辑
接受的答案纠正了原始正则表达式中的一个拼写错误(缺少^
(,其注释回答了以下问题:为什么^
可以是"0";"重复使用";在后备而不是在zs
的情况下?(答:后备不消耗比赛,而zs
消耗。(
这里的要点是(a{2}a{-})@<=a
匹配任何前面有两个或多个a
字符的a
(请参阅最后一个a
(。在NFA regex风格中,它等于(?<=a{2,}?)a
,请参阅其演示。
^a{2}a{-}zsa
正则表达式匹配字符串的开头,然后匹配两个或多个a
,然后丢弃此匹配的文本并匹配一个a
。因此,它无法匹配其他a
,因为^
将匹配锚定在字符串的开头(并且它不允许在其他任何地方匹配(。
您可能想继续使用lookbacking构造,并在那里添加^
(如果您只想在字符串以两个a
开头时开始匹配(:
:%s/v(^a{2}a{-})@<=a/X/g