Positive and Negative Lookbehind — (?<=...) and (?<!...) Explained

Deep dive into positive lookbehind (?<=...) and negative lookbehind (?<!...) with practical examples for currency, prefixes, and pre-context filtering.

Advanced Techniques

Detailed Explanation

Positive and Negative Lookbehind

Lookbehind assertions check the text immediately preceding the current position without consuming it. They were added to JavaScript in ES2018 and are fully supported in modern engines (Node 10+, all current browsers).

Positive Lookbehind (?<=X)

Matches a position preceded by X.

(?<=\$)\d+(?:\.\d+)?

Extracts numeric prices that are preceded by $. In "Save $20 today", matches 20.

Negative Lookbehind (?<!X)

Matches a position NOT preceded by X.

(?<!\d)\.\d+

Matches .42 only when there is no digit before the dot (rejecting 3.14).

Variable-Length Lookbehind

Modern V8 supports variable-length lookbehinds:

(?<=https?:\/\/[^\s/]+)\/[^\s]+

Matches the path portion of a URL (anything after the host).

Tested Examples

Pattern Input Match
(?<=\$)\d+ "$100" 100
(?<!#)[a-f0-9]{6} "hex abc123 not #abc123" abc123 (without #)
(?<=class=")[\w ]+ 'class="btn primary"' btn primary
(?<=^)\d+ "123abc" 123
(?<!\w)cat "a cat sits" cat

Lookbehind vs Capture Group

You could match $100 with \$(\d+) and reference $1. The lookbehind version is cleaner when you want the match itself to exclude the prefix, which simplifies downstream code that uses match[0].

Combining with Lookahead

(?<=\$)\d+(?=\s|$)

Matches a price preceded by $ and followed by whitespace or end of string, ignoring $1234567890 embedded in larger strings.

Browser Support Note

Lookbehind shipped in V8 7.6 (Chrome 76, Node 10+), Safari 16.4, and Firefox 78. If you need to support older Safari, use a polyfill or rewrite with capture groups.

Practical Use Cases

  • Extract values after a known prefix (currency, units, tags)
  • Skip matches that are commented out (preceded by //)
  • Find isolated occurrences of a substring

Use Case

Extracting prices preceded by a currency symbol from product descriptions, filtering matches that should not have certain prefixes (already-prefixed slugs), or pulling values out of HTML attributes without including the attribute name.

Try It — Regex Cheat Sheet

Open full tool