正则表达式:使用行首重复匹配
Regex: repeated matches using start of line
说我想替换 2 个初始 a
之后的所有 a
,并且它和前 2 个 [=13] 之间只有 a
=]秒。我可以在 Vim 中使用(非常神奇 \v
)正则表达式 s:\v(^a{2}a{-})@<=a:X:g
:
aaaaaaaaaaa
去
aaXXXXXXXXX
但是,为什么 s:\v^a{2}a{-}\zsa:X:g
只替换第一个出现的地方?即,给予
aaXaaaaaaaa
我认为这是因为第一个匹配“消耗”了行的开头和前 2 个 a
,因此后面的匹配只匹配行的剩余部分,永远无法匹配^
再次。这是真的?或者更确切地说,最有教育意义的解释是什么?
P.S。这是另一个问题的最小示例。
编辑
已接受的答案更正了原始正则表达式中的错字(缺少 ^
),其评论回答了以下问题:为什么 ^
可以在回顾中“重用”,但不能在 \zs
案例? (回答:lookbehind 不消耗匹配,而 \zs
消耗匹配。)
这里的要点是 (a{2}a{-})@<=a
匹配前面有两个或更多 a
字符的任何 a
(请参阅最后一个 a
)。在 NFA 正则表达式中,它等于 (?<=a{2,}?)a
,参见 its demo。
^a{2}a{-}\zsa
正则表达式匹配字符串的开头,然后是两个或更多 a
s,然后丢弃这个匹配的文本并匹配一个 a
。因此,它无法匹配其他 a
,因为 ^
将匹配锚定在字符串的开头(并且它不允许匹配其他任何地方)。
您可能想继续使用后向构造并在其中添加 ^
(如果您只想在字符串以两个 a
开头时才开始匹配):
:%s/\v(^a{2}a{-})@<=a/X/g
说我想替换 2 个初始 a
之后的所有 a
,并且它和前 2 个 [=13] 之间只有 a
=]秒。我可以在 Vim 中使用(非常神奇 \v
)正则表达式 s:\v(^a{2}a{-})@<=a:X:g
:
aaaaaaaaaaa
去
aaXXXXXXXXX
但是,为什么 s:\v^a{2}a{-}\zsa:X:g
只替换第一个出现的地方?即,给予
aaXaaaaaaaa
我认为这是因为第一个匹配“消耗”了行的开头和前 2 个 a
,因此后面的匹配只匹配行的剩余部分,永远无法匹配^
再次。这是真的?或者更确切地说,最有教育意义的解释是什么?
P.S。这是另一个问题的最小示例。
编辑
已接受的答案更正了原始正则表达式中的错字(缺少 ^
),其评论回答了以下问题:为什么 ^
可以在回顾中“重用”,但不能在 \zs
案例? (回答:lookbehind 不消耗匹配,而 \zs
消耗匹配。)
这里的要点是 (a{2}a{-})@<=a
匹配前面有两个或更多 a
字符的任何 a
(请参阅最后一个 a
)。在 NFA 正则表达式中,它等于 (?<=a{2,}?)a
,参见 its demo。
^a{2}a{-}\zsa
正则表达式匹配字符串的开头,然后是两个或更多 a
s,然后丢弃这个匹配的文本并匹配一个 a
。因此,它无法匹配其他 a
,因为 ^
将匹配锚定在字符串的开头(并且它不允许匹配其他任何地方)。
您可能想继续使用后向构造并在其中添加 ^
(如果您只想在字符串以两个 a
开头时才开始匹配):
:%s/\v(^a{2}a{-})@<=a/X/g