JavaScript RegExp (?=...) Positive Lookahead

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Zero-width assertion

What You’ll Learn

The (?=...) syntax is a positive lookahead assertion. It lets you match text only when it is followed by a required pattern—without consuming that following text. It is zero-width, ideal for conditional matching and multi-rule validation.

01

(?=...)

Must follow

02

Zero-width

Peek, don’t eat

03

Assertion

Not + or *

04

Require

Suffix rules

05

vs (?!)

Negative twin

06

Stack

Multi rules

Introduction

Negative lookahead says “only match if the next text is not X.” Positive lookahead flips that rule: “only match if the next text is X.” For example, match foo only when immediately followed by bar: /foo(?=bar)/.

Like (?!...), the positive form is an assertion, not a repetition quantifier. It peeks ahead, checks a condition, and never adds the lookahead text to your match result. That makes it perfect when you need a suffix check but want to return only the prefix.

Understanding (?=...) Positive Lookahead

Syntax: (?=pattern). At the current position, the engine tries to match pattern against the upcoming characters. If it succeeds, the assertion passes and matching continues; if it fails, the overall match fails at this point.

JavaScript
const samples = ["foobar", "foobaz", "foo"];

samples.forEach((s) => {
  console.log(s, s.match(/foo(?=bar)/));
});
// foobar ["foo"]
// foobaz null
// foo    null

In "foobar", foo is followed by bar, so the assertion passes and the match returns "foo". In "foobaz", the required bar is missing, so the match fails entirely.

💡
Beginner Tip

Read (?=bar) as “followed by bar.” Compare with (?!bar), which means “not followed by bar.”

How to Use Positive Lookahead

Place (?=...) after the text you want to conditionally match, or chain several at the start for password-style rules:

JavaScript
/foo(?=bar)/;                       // foo followed by bar
/\d+(?= dollars)/g;                 // numbers before " dollars"
/^(?=.*\d).{8,}$/;                  // 8+ chars with a digit
/^(?=.*[a-z])(?=.*[A-Z]).{8,}$/;   // upper + lower + length
new RegExp("http(?=s)");            // constructor form

"https://x.com".match(/http(?=s)/); // ["http"]

Use the global flag to find every qualifying match. At the start of a pattern, (?=.*rule) checks that the whole string contains something without moving the main match cursor.

📝 Syntax

JavaScript
(?=pattern)          // positive lookahead — MUST follow
(?!pattern)          // negative lookahead — must NOT follow
(?=foo|bar)          // followed by foo OR bar
^(?=.*\d).+$         // whole string contains a digit
token(?=suffix)      // token only when suffix present

Common patterns

  • /foo(?=bar)/ — match foo only when bar follows.
  • /http(?=s)/ — match http in https URLs.
  • /\d+(?= dollars)/g — dollar amounts without matching the word.
  • /^(?=.*@gmail\.com$).+@.+/ — emails that must be Gmail.
  • /^(?=.*[A-Z])(?=.*\d).{8,}$/ — password with uppercase and digit.

⚡ Quick Reference

GoalPattern / API
Followed by text/part(?=suffix)/
Match https prefix/http(?=s)/
Number before unit/\d+(?= px)/g
Must contain digit/^(?=.*\d).+$/
Negative counterpart(?!pattern)
Does not consume inputZero-width — not in match result

📋 Positive vs Negative Lookahead

(?=...) requires what follows; (?!...) forbids it.

Positive
(?=bar)

MUST be followed by bar

Negative
(?!bar)

Must NOT be followed by bar

On "foobar"
/foo(?=bar)/

Matches foo

On "foobaz"
/foo(?=bar)/

No match — bar absent

Examples Gallery

Open DevTools Console (F12) or use Try-it links. Examples cover basic suffix requirements, secure URLs, dollar amounts, digit validation, and stacked password rules.

📚 Getting Started

Match text only when a required suffix is present.

Example 1 — Match foo Followed by bar

Use /foo(?=bar)/ to require the bar suffix.

JavaScript
const words = ["foobar", "foobaz", "foo"];

words.forEach((w) => {
  console.log(w, w.match(/foo(?=bar)/));
});
// foobar ["foo"]
// foobaz null
// foo    null
Try It Yourself

How It Works

After matching foo, the engine verifies that bar comes next. The returned match is only foo—the lookahead portion is not included.

📈 Practical Patterns

URLs, amounts, and validation rules.

Example 2 — Match http in https URLs

Detect secure protocol prefix with /http(?=s)/.

JavaScript
const urls = [
  "https://secure.com",
  "http://plain.com",
  "ftp://files.com"
];

urls.forEach((url) => {
  console.log(url, url.match(/http(?=s)/));
});
// https://secure.com ["http"]
// http://plain.com   null
// ftp://files.com    null
Try It Yourself

How It Works

The pattern matches http only when s immediately follows—as in https. Plain http:// fails because the next character is :, not s.

Example 3 — Numbers Followed by dollars

Extract numeric amounts without including the currency word.

JavaScript
const text = "5 dollars and 10 coins and 3 dollars";

const amounts = text.match(/\d+(?= dollars)/g);
console.log(amounts); // ["5", "3"]
Try It Yourself

How It Works

\d+ matches the number; (?= dollars) confirms the word dollars comes next. The match result contains only the digits—a clean split between value and unit.

Example 4 — Require at Least One Digit

Validate length and digit presence with a start-of-string lookahead.

JavaScript
const rule = /^(?=.*\d).{8,}$/;

console.log(rule.test("Secret1!"));  // true
console.log(rule.test("Secret!!"));  // false — no digit
console.log(rule.test("Sh0rt"));     // false — too short
Try It Yourself

How It Works

(?=.*\d) scans the entire string for any digit without consuming it. Then .{8,}$ enforces minimum length. Both conditions must pass.

Example 5 — Stack Multiple Lookahead Rules

Chain lookaheads for uppercase, lowercase, and length requirements.

JavaScript
const strong = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;

console.log(strong.test("Abcdef1!"));  // true
console.log(strong.test("abcdef1!"));  // false — no uppercase
console.log(strong.test("Abcdefgh"));  // false — no digit
Try It Yourself

How It Works

Each (?=...) at the start checks one rule against the whole string. All must succeed before .{8,}$ validates length. This pattern is a common password-strength building block.

🚀 Common Use Cases

  • Suffix requirements — match tokens only when a specific unit or keyword follows.
  • Protocol detection — distinguish https from http at the prefix level.
  • Password rules — require digits, cases, or symbols with chained (?=.*...) checks.
  • Partial extraction — return numbers or words without their trailing context.
  • Format guards — ensure IDs, SKUs, or codes are followed by expected separators.
  • Conditional parsing — match a keyword only in a specific grammatical context.

Important Considerations

  • Zero-width — matched text never includes the lookahead portion.
  • Not a quantifier(?=...) does not repeat characters; it adds a condition.
  • Order matters — place lookaheads before the part of the pattern they gate.
  • .* in lookaheads(?=.*\d) scans the whole string; useful for “must contain” rules.
  • Performance — many stacked lookaheads on huge strings can slow matching; keep rules focused.
  • Lookbehind alternative — for “must be preceded by” rules, use (?<=...) (ES2018) instead.

🧠 How Positive Lookahead Works

1

Match preceding part

The engine matches literal text or groups before (?=...).

Pattern
2

Peek ahead

At the current position, try to match the inner pattern without advancing the cursor.

Lookahead
3

Require a match

If inner pattern matches, assertion succeeds. If not, the engine backtracks or fails.

Assert
4

Continue matching

On success, the rest of the pattern runs. The lookahead text stays outside the final match.

📝 Notes

  • Negative counterpart: (?!...) negative lookahead.
  • Previous topic: + one-or-more quantifier.
  • Next topic: ? zero-or-one quantifier.
  • Stack lookaheads at ^ for whole-string “must contain” validation.
  • See [0-9] and \d for digit checks inside lookaheads.
  • Positive lookahead differs from simply writing the suffix in the pattern—the suffix is not captured in the result.

Browser & Runtime Support

Positive lookahead (?=...) is part of core JavaScript regular expression syntax.

Baseline · ES3+

RegExp (?=...) lookahead

Supported in every browser and Node.js version. No polyfill needed for positive lookahead assertions.

99% Universal syntax
Google Chrome Supported · Desktop & Mobile
Full support
Mozilla Firefox Supported · Desktop & Mobile
Full support
Apple Safari Supported · macOS & iOS
Full support
Microsoft Edge Supported · Chromium
Full support
Internet Explorer No native support · Use a polyfill
Polyfill
Opera Supported · Modern versions
Full support
Samsung Internet Supported · Android
Full support
Bun Supported · JavaScript runtime
Supported
Deno Supported · JavaScript runtime
Supported
Node.js Supported · Server runtime
Supported
Android WebView Supported · Modern WebView
Full support
(?=...) Excellent

Bottom line: Safe everywhere. Use (?=...) when a match requires specific following text without consuming it.

Conclusion

The (?=...) positive lookahead lets you match text only when required characters follow. It is zero-width, pairs naturally with validation rules, and complements (?!...) negative lookahead for precise conditional matching.

Use it for suffix checks, secure URL detection, and stacked password requirements. Remember the lookahead text never appears in the match result. Next, learn the ? optional quantifier.

💡 Best Practices

✅ Do

  • Read (?=x) as “followed by x”
  • Use ^(?=.*rule) for “must contain” checks
  • Stack lookaheads for multiple independent validation rules
  • Add g when finding every qualifying match
  • Compare with (?!...) when you need the opposite rule

❌ Don’t

  • Expect lookahead text in the match result
  • Call (?=...) a repetition quantifier
  • Forget that foo(?=bar) fails on plain foo
  • Over-stack lookaheads without testing readability
  • Use lookahead when including the suffix in the match is simpler

Key Takeaways

Knowledge Unlocked

Five things to remember about (?=...) positive lookahead

Require following text without consuming it.

5
Core concepts
👁 02

Zero-width

Peek only.

Concept
📈 03

Assertion

Not + or *.

Type
🔒 04

^(?=.*\d)

Need digit.

Validate
🚫 05

(?!...)

Opposite rule.

Compare

❓ Frequently Asked Questions

(?=...) is a positive lookahead assertion. It succeeds when the text immediately after the current position DOES match the pattern inside the parentheses. It is zero-width—it checks ahead without consuming characters.
No. Although some tutorials label it a quantifier, (?=...) is an assertion—a condition on what follows. Quantifiers like + and * repeat the previous token. Lookahead only peeks at upcoming text without including it in the match.
(?=...) requires the following text to match the inner pattern. (?!...) requires the following text NOT to match. Both are zero-width and do not consume input.
Yes. Patterns like /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/ chain several lookaheads at the start. Each must succeed before the rest of the pattern matches.
Lookahead lets you require following text without including it in the match result. /\d+(?= dollars)/ matches 5 in 5 dollars but returns only 5, not 5 dollars.
Positive lookahead is core JavaScript regex syntax since ES3. It works in every browser and Node.js version without polyfills.
Did you know?

Password validators often chain three or more positive lookaheads at ^ because each one checks an independent rule (“has a digit,” “has uppercase,” etc.) without caring about order. The main pattern at the end—usually .{8,}$—handles minimum length in one place.

Continue to ? optional quantifier

Learn how ? makes the previous token optional—zero or one time.

? quantifier tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful