Development

Regex Lookahead and Lookbehind: A Visual Guide

The Debuggers Team
8 min read

Advanced regex patterns with lookahead and lookbehind operators

Regular Expressions are easy until they aren't. You master *, +, and ?. You feel confident. Then you see this: (?<=@)(?<!\.)

Lookaheads and Lookbehinds (collectively called "Lookarounds") are the most powerful features in Regex, yet the most misunderstood.

In this guide, we will demystify them. (You can test all these patterns live in our Regex Tester).

What is a Lookaround?

A Lookaround asserts that "X is followed by Y", but it does not consume characters. It just checks a condition.

Think of it like a cursor.

  • Normal Match: cat matches "cat" and moves the cursor past "t".
  • Lookahead: (?=cat) checks if "cat" is there, but leaves the cursor where it was.

1. Positive Lookahead (?=...)

  • "Match this position if it is followed by..."

Example: Match "USD" only if followed by a number.

Text: USD 100, EUR 50, USD text Regex: USD(?=\s\d) Match: The first USD only.

2. Negative Lookahead (?!...)

  • "Match this position if it is NOT followed by..."

Example: Match "Windows" only if it is NOT "Windows 95".

Text: Windows 98, Windows 95, Windows 10 Regex: Windows(?!\s95) Matches: Windows (in 98), Windows (in 10).

The Killer Use Case: Password Validation

How do you validate: "Must contain 1 uppercase, 1 lowercase, 1 number, and be 8 chars long"?

Without lookaheads, this is impossible in one regex. With lookaheads, it's easy:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$

Breakdown:

  1. ^ : Start of line.
  2. (?=.*[a-z]) : Scan ahead. Is there a lowercase letter? Good. Reset cursor to start.
  3. (?=.*[A-Z]) : Scan ahead. Is there an uppercase letter? Good. Reset cursor to start.
  4. (?=.*\d) : Scan ahead. Is there a number? Good. Reset cursor to start.
  5. .{8,}$ : Okay, now actually match 8+ chars.

3. Lookbehind (?<=...)

  • "Match this position if it is preceded by..."

Example: specific price value without the currency symbol.

Text: Price: $50 Regex: (?<=\$)\d+ Match: 50 (It sees the $, but only captures the number).

4. Negative Lookbehind (?<!...)

  • "Match this position if it is NOT preceded by..."

Example: Match "foo" but not if it's "barfoo".

Text: myfoo, barfoo Regex: (?<!bar)foo Match: The foo in "myfoo".

Browser Support Note

Lookbehinds are newer (ES2018). They work in Chrome, Firefox, and Node.js, but failed in older Safari versions. Always check support if you need to support Internet Explorer (RIP).

Conclusion

Lookarounds allow you to validate conditions without "eating" the characters, enabling complex logic like intersection ("must contain X AND Y").

They perform best when tested visually. Paste your complex passwords into our Regex Tester to see exactly which lookahead is failing.

Need Help Implementing This in a Real Project?

Our team supports end-to-end development for web and mobile software, from architecture to launch.

regex lookaheadregex lookbehindregex password validationregex testeradvanced regex

Found this helpful?

Join thousands of developers using our tools to write better code, faster.