ToolBoxOnline
Developer

Regex Lookahead and Lookbehind: Matching What Comes Next to the Match

You've mastered the basics — and you're still stuck writing 'password must contain a letter' checks. Lookahead and lookbehind are the tools you're missing.

regex lookaheadregex lookbehindregular expressionspassword validationzero-width assertion

You're building a signup form and you need a rule: the password must contain at least one letter, one number, and be at least eight characters. The naive approach is three separate checks, or one giant regex that reads like a ransom note. Then a colleague mentions "lookahead" and "lookbehind," and suddenly you're supposed to write assertions that match things without consuming them. If those words make your eyes glaze over, this is the article for you — because these two zero-width assertions are the difference between fighting regex and letting it do the work.

The Problem Lookahead Solves

A normal pattern consumes characters as it matches. That's why a password check like ^(?=.*[a-z]) looks alien: the (?=...) is a lookahead. It looks forward, checks that the thing inside exists somewhere ahead, and then moves on without consuming anything — which is exactly what you want when you're stacking requirements. The pattern above means "at the start, somewhere ahead, there's a lowercase letter." You can chain them: (?=.*[a-z])(?=.*[0-9]) verifies both a letter and a digit exist, anywhere, in one expression. The counter-intuitive part is that nothing is actually matched — the assertions are just checkpoints that must pass.

Lookbehind: The Other Direction

Lookbehind is the mirror: it checks what came before the match position. The canonical case is prices — you want to match the number after a dollar sign without including the sign. (?<=$)d+ matches "49" in "$49" but not in "49", because it requires a dollar sign immediately behind. The mistake most people make is reaching for a capturing group and then writing code to strip the extra character — lookbehind removes the need for that dance entirely. Test both directions side by side in the regex tester and the zero-width behavior becomes obvious: highlight the match and notice the cursor didn't advance past the assertion.

The Traps Nobody Warns You About

The counter-intuitive part is that lookarounds change how you think about matching. A (?!...) negative lookahead is how you say "not followed by" — the classic "match foo not followed by bar." But people use it to mean "not containing," which is wrong. And lookbehind has a hard limit in most engines: fixed-length only. The text-diff tool compares strings line by line, but regex assertions compare positions — a different kind of diff. When you finally have an expression that passes, drop it into the code formatter for the surrounding script, and future-you will thank past-you for the comments.

We covered the greedy-versus-lazy trap in our guide to lazy vs greedy quantifiers. Lookahead and lookbehind are the next rung — match the requirements, not the characters, and the password check writes itself.

Tools mentioned in this article

Share this tool