Assert that something follows, without consuming it
(?=...) says "at the current position, the pattern inside the lookahead matches." The engine confirms but does not consume. Whatever's after the lookahead in the main pattern continues from the same position.
Three real uses
Constrain a match by what follows. \d+(?= dollars) matches a number ONLY IF "dollars" follows. Notice: 'dollars' is required for the match to succeed, but it's not part of the captured value.
Stack multiple requirements at the same position. (?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,} — "at the start, all three must be true: contains lowercase, contains uppercase, contains a digit, AND is 8+ chars." Each lookahead is a separate constraint, all anchored at the same position.
Find positions for splits without including the boundary. Useful with re.split when you want to split BEFORE a marker but keep it in the next chunk.
The cursor doesn't move
Critical mental model: after the lookahead succeeds, the engine is at the SAME position as before the lookahead. Anything written after the lookahead in the pattern starts matching from that position. So \d+(?=kg)kg would match the digits AND then re-match the 'kg' (because the cursor never moved past the lookahead's content).