Lookaheads in JavaScript Regex

Introduction

Welcome back to Regex Validation, Flags, and Text Processing in JavaScript! You've now completed two lessons, and your regex skills are growing impressively. In the first lesson, you learned to validate complete inputs with the .test() method combined with anchors (^ and $), creating username and password validators that check every character from start to finish. In the previous lesson, you mastered regex flags to control pattern behavior: performing case-insensitive searches with the i flag, handling line boundaries with the m flag, and matching across newlines with the s flag. These tools give you tremendous flexibility in how patterns process text.

However, there's another challenge that neither validation rules nor flags directly solve: what if you need to match text based on what comes before or after it, but without including that context in the match itself? Imagine extracting dollar amounts, but only when they're followed by the word "USD"; or finding passwords in a configuration file, but excluding any marked as "REDACTED"; or validating that a password contains both uppercase and lowercase letters without caring about their order. These scenarios require checking conditions without consuming the characters being checked. This lesson introduces lookaheads: powerful assertions that let you peek ahead in the text to verify conditions without including those characters in your match. Let's explore how lookaheads enable sophisticated conditional matching.

Understanding Lookaheads and Zero-Width Assertions

Lookaheads are a type of zero-width assertion: they check whether a pattern exists at a specific position without actually consuming any characters. Think of them as looking ahead in the text to verify something is there, then stepping back to continue matching from where you were. This "look but don't consume" behavior is fundamentally different from normal pattern matching, where the regex engine advances through the string as it matches each component.

There are two types of lookaheads in JavaScript's regex engine:

  • Positive lookaheads (?=...) succeed if the pattern inside matches at the current position, but they don't advance the matching position.
  • Negative lookaheads (?!...) succeed if the pattern inside does not match at the current position, again without consuming characters.

Consider extracting prices from text where some are in USD and others in EUR. A normal pattern like /\d+\.\d{2} USD/ would match "12.50 USD," but it includes " USD" in the captured result. With a positive lookahead /\d+\.\d{2}(?= USD)/, you match the price only if it's followed by " USD," but the lookahead doesn't consume " USD," so your match contains just the numeric amount. Similarly, negative lookaheads let you exclude matches based on what follows. These assertions become especially powerful for validation, where you need to ensure certain characters exist somewhere in the string without caring about their exact position.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal