Regexdrill

Groups and lookarounds Updated November 2026

Lookahead (?=...) and (?!...)

A lookahead (?=X) checks that X follows the current position without consuming it; a negative lookahead (?!X) checks that it does not. \d+(?= USD) matches a number only when USD follows, and \b(?!un)\w+ matches words that do not start with un. Lookaheads power password rules and must-not-contain checks.

Syntax

(?=X)  positive      (?!X)  negative

Examples

"100 USD, 200 EUR, 300 USD".match(/\d+(?= USD)/g)

Result: ["100", "300"]

USD is checked but not included in the match.

"undo redo unzip".match(/\b(?!un)\w+/g)

Result: ["redo"]

"1234567".replace(/\B(?=(\d{3})+$)/g, ",")

Result: "1,234,567"

Insert a comma at every position followed by a multiple of three digits.

["app.js", "app.min.js", "app.ts"].filter(f => /^(?!.*\.min\.js$).*\.js$/.test(f))

Result: ["app.js"]

Ends with .js but not with .min.js.

Common mistakes

  • Expecting the lookahead text to be part of the match; it is only checked. Capture it separately if you need it.
  • Writing (?!foo) without .* to mean "does not contain foo anywhere"; use ^(?!.*foo) at the start of the pattern.
  • Putting a lookahead at the end of the string check, (?=$), where plain $ already does the job.
  • Using lookaheads in tools that do not support them, such as basic grep or sed; use grep -P or a language regex.

Practice Lookahead (?=...) and (?!...)

These drills check your answer on live data, free, no account needed.

Questions

What is the difference between lookahead and lookbehind?

Lookahead (?=X) looks at what comes after the current position; lookbehind (?<=X) looks at what comes before. Neither consumes characters or appears in the match.

How do I match a string that does not contain a word?

^(?!.*\bword\b).*$ : the negative lookahead at the start scans the whole string first. Add the s flag if the string has line breaks.

Are lookaheads supported everywhere?

JavaScript, Python, PCRE (PHP), Java, .NET, Go (RE2 does not), Ruby and Excel 365 support them. POSIX tools like basic grep and sed do not.

Related

  • Lookbehind (?<=...) and (?<!...)How lookbehind checks what precedes the match, grabbing the number after a dollar sign or excluding negatives, browser and Python support, and width limits.
  • Regex for passwordA password regex built from one lookahead per rule plus a length check, how (?=.*X) works, how to report which rule failed, and the mistakes that weaken it.
  • Negated character classHow [^...] matches any character except the listed ones, stripping non-digits, grabbing quoted text, splitting on a delimiter, and how it differs from (?!).
  • Anchors ^ and $What ^ and $ match, how they change with the m flag, whole-string versus per-line matching, and the mistakes with alternation and trailing newlines.

Previous: Backreferences \1Next: Lookbehind (?<=...) and (?<!...)