The canonical multi-rule example
"Password must be 8+ chars, contain at least one lowercase, one uppercase, and one digit." Without lookahead, this is a nightmare: enumerating every order in which the required characters can appear.
With stacked lookaheads, it's clean:
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$
Reading left to right:
^— start of string(?=.*[a-z])— somewhere ahead is a lowercase letter(?=.*[A-Z])— somewhere ahead is an uppercase letter(?=.*\d)— somewhere ahead is a digit.{8,}— actually consume 8+ characters$— end of string
The three lookaheads run AT THE START. Each peeks ahead to verify a constraint exists somewhere in the string. After all three pass, the pattern proceeds to consume 8+ characters.
Why this is the textbook example
It demonstrates everything important about lookaround:
- Multiple constraints stacked at the same position.
- Each constraint independent (order doesn't matter).
- The final consume is separate from the constraints.
- The result reads almost like a spec.
Adding more rules
Need at least one special character? Add (?=.*[!@#$%^&*]). Need to forbid spaces? Add (?!.*\s) (negative lookahead). The pattern grows linearly, not exponentially.