chrome-extension://regex-tester-pro · live preview

Pattern

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

Test string

Total: $249.50 (USD).

flags: g · 1 match · 0.4 ms

All matching happens in your browser. Patterns and test strings never leave the tab.

Regex Guide

Regex Lookahead and Lookbehind, Explained With Real Patterns

Updated May 2026 8 min read By the Regex Tester Pro team

Quick answer

Lookaheads and lookbehinds are zero-width assertions: they check what is on either side of a position without consuming characters. Use them when you need to match something only in a specific context, such as a price preceded by a currency symbol or a tag not followed by a closing slash.

Lookaround is the feature that turns regex from "find this string" into "find this string in this context". Once you understand the four forms, a class of problems that needed two regexes or a callback becomes a single readable pattern.

JavaScript
// All four lookaround forms, by example
const text = 'Buy at $249.50 or 99 cents off MSRP $300';

// Positive lookahead: digits followed by " cents"
text.match(/\d+(?= cents)/);             // ['99']

// Negative lookahead: digits NOT followed by " cents"
[...text.matchAll(/\d+(?! cents)/g)]
  .map(m => m[0]);                       // ['249', '50', '300']

// Positive lookbehind: digits preceded by $
[...text.matchAll(/(?<=\$)\d+(?:\.\d{2})?/g)]
  .map(m => m[0]);                       // ['249.50', '300']

// Negative lookbehind: digits NOT preceded by $
[...text.matchAll(/(?<!\$)\d+/g)]
  .map(m => m[0]);                       // ['99'] (numbers without leading $)

What "zero-width" actually means

Most regex tokens consume characters: a matches and consumes one a. Anchors and lookarounds do not consume. They only check the position. After a successful match, the engine's cursor stays where it was before the assertion.

That is why you can chain assertions: (?=\d)(?=[02468]) matches a position where the next character is both a digit and even (i.e. an even digit). Each lookahead checks the same position from the same starting point.

Practical implication: lookarounds let you express "this character must exist in this context, and the match should be the character itself, not the surrounding context". Without them you would have to capture the surrounding context and discard it.

Positive lookahead: "must be followed by"

Syntax: (?=...). Match the position only if what follows matches the inner pattern. Examples:

The last pattern is the canonical reason developers reach for lookahead: chained assertions give you AND-style constraints inside a single regex.

Negative lookahead: "must NOT be followed by"

Syntax: (?!...). The position matches only if the inner pattern would not match starting there. Examples:

Negative lookahead is also how you write "match X unless Y is right after it" without a second pass.

Lookbehind: "must be preceded by"

Syntax: (?<=...) for positive, (?<!...) for negative. Same idea as lookahead but checks what is before the current position.

Lookbehind support: stable in V8 (Chrome, Node), Firefox, and Safari 16.4+. Python's built-in re requires fixed-width lookbehind; for variable-width, install the regex module. PCRE supports both.

Where lookaround quietly outperforms alternatives

Three classes of problems where lookaround is the right tool:

  1. Extracting in context. "All numbers preceded by $" is one regex with lookbehind, two passes without.
  2. Validation with multiple constraints. Password rules, structured-input checks (must contain letter AND digit AND symbol), all expressed as chained lookaheads.
  3. Splitting without losing the delimiter. str.split(/(?<=\.)\s+/) splits a paragraph into sentences while keeping the period at the end of each sentence (because the lookbehind does not consume the period).

When to skip lookaround

Three signs you should reach for something else:

Otherwise, lookaround is the difference between regex that reads like a question and regex that reads like a hieroglyph.

See lookaround highlighted live

Regex Tester Pro gives you live matching, named groups, replacements, and reference cheatsheets in one Chrome popup. Free, private, no signup.

Add to Chrome, free

Frequently asked questions

Does lookaround consume characters?
No. After a lookaround matches, the cursor stays at the same position it was before. Only the inner check has happened.
Can I nest lookarounds?
Yes. (?=\d)(?=[02468]) chains two positive lookaheads at the same position. Useful for expressing AND-style constraints.
Why does my Python lookbehind throw an error?
The built-in re module requires fixed-width lookbehind. Switch to the regex package on PyPI for variable-width support.
Does V8 support all four lookaround forms?
Yes since 2018 (Chrome 62 and Node 10+). Both lookahead and lookbehind, positive and negative, with full ES2018 syntax.
Can lookaround use capture groups?
Yes. The groups are captured even though the lookaround does not consume the input. Useful for documenting which part of the context matched.

More by Peak Productivity

Free developer tools, made for the browser

Privacy-first utilities that run locally. No upload, no signup, no watermark.