The cursor stays where it is
The single most important property of lookaround: after the assertion runs, the engine is at the same position as before. No characters have been consumed.
This has two practical consequences:
1. Multiple lookarounds at one position chain naturally. Each one peeks from the same spot. (?=A)(?=B)(?=C) means "A AND B AND C all match starting from here."
2. The text inside the lookaround can OVERLAP with subsequent matches. (?=cat)\w+ first asserts 'cat' starts here, then matches \w+ which actually consumes 'cat' (and possibly more). Same characters, two roles.
Compare to consuming alternatives
Pattern cat\d+ consumes 'cat' and then matches digits. After this, the cursor is past the digits.
Pattern (?=cat)\d+ would never match — it asserts 'cat' here, then tries to match digits AT THE SAME POSITION, but the position is 'c', not a digit.
Pattern (?=cat\d)cat\d+ works — assert 'cat' then a digit follows, then actually match cat and the digits.
Why this matters for splits
Zero-width matching is what lets re.split(r'(?=[A-Z])', 'CamelCase') split at every uppercase letter without DELETING the uppercase letter. The split position is detected without consuming the boundary character.