Regex Lookahead and Lookbehind Explained

Lookahead and lookbehind are zero-width assertions — they check what's around a match without consuming characters. The matched text doesn't include the lookahead/lookbehind itself.

Positive lookahead (?=...)

Match foo only when followed by bar:

/foo(?=bar)/
"foobar"   → matches "foo"
"foobaz"   → no match
"foobarfoo" → matches first "foo"

The bar part is checked but not included in what's captured.

Negative lookahead (?!...)

Match foo only when not followed by bar:

/foo(?!bar)/
"foobar"  → no match
"foobaz"  → matches "foo"

Useful for excluding a pattern: match a word that isn't a reserved keyword, or a number not followed by px.

Positive lookbehind (?<=...)

Match bar only when preceded by foo:

/(?<=foo)bar/
"foobar"  → matches "bar"
"bazbar"  → no match

Negative lookbehind (?<!...)

Match bar only when not preceded by foo:

/(?<!foo)bar/
"foobar"  → no match
"bazbar"  → matches "bar"

Real-world examples

Match a price number without the $ sign:

/(?<=\$)\d+(\.\d{2})?/

Captures 9.99 from $9.99, leaving out the dollar sign.

Match a word not at the end of a sentence:

/\b\w+\b(?![.!?])/g

Strip leading zeros from a number:

"007".replace(/(?<=^)0+/, "")  // "7"

Browser and Node.js support

Lookbehind ((?<=...), (?<!...)) was added in ES2018. It works in Chrome, Firefox, Safari 16.4+, and Node.js 10+. If you're targeting older environments, stick to lookahead only.

Quick reference

SyntaxNameMatches when...
(?=...)Positive lookaheadFollowed by pattern
(?!...)Negative lookaheadNOT followed by pattern
(?<=...)Positive lookbehindPreceded by pattern
(?<!...)Negative lookbehindNOT preceded by pattern

Test it live

Paste any regex and test string into the regex tester to see matches highlighted in real time — no setup needed. For more patterns to build on, see common regex patterns or the full regex cheat sheet.

Got a config file to check?

Open the config toolkit →