This won't work because Vim won't scan the same text twice trying to match a different regex.
Even though the \zs
makes the resulting match only include the b
s, Vim needs to see all the a
s to be able to match that regex and it won't do so if it already matched the a
s to the other pattern.
You can do a small experiment to see this behavior, by doing a simple search for the two regexes:
/^a\+\|^a\+\zsb\+
You'll see that the search will match the a
s, but not the b
s.
(On the other hand, replacing the a
in the first regex with a different character matches both lines starting with that other character and lines with the b
s following the a
s, which proves the regex otherwise works as expected.)
To work around this issue, use a zero-width lookup match, using \@<=
to match the series of a
s at the start of the line preceding the b
s.
You can use this match instead:
syntax match xB /\(^a\+\)\@<=b\+/
You'll notice this pattern also works correctly in the search experiment:
/^a\+\|\(^a\+\)\@<=b\+
The reason why this works is that Vim will first search for b
s and then look behind to see if that other part of the regex also matches. So the pattern gets anchored on b
rather than a
and doesn't suffer from the issue of trying to start a match on a region that already matched another expression.
Please note that zero-width lookups such as this one can have performance side effects, if the regex is too generic Vim might end up going pretty far trying to look for the start of a match. See :help /\@<=
for more details.