JavaScript RegExp d Flag

Beginner
6 min read
Updated: Oct 2026
3 examples
ES2022

What Is the d Flag?

The d flag (also called hasIndices) adds an indices property to match results. Each entry is a [start, end) range for the full match and every capture group—same half-open style as String.slice.

Remember
/pattern/d          // enable indices
regex.hasIndices    // true when d is set

match.indices[0]    // [start, end) full match
match.indices[1]    // [start, end) group 1
match.indices.groups // named group ranges

d flag ≠ \d digit metacharacter
UsePrefer
Group positions/…/d + match.indices
Every match + positions/…/gd + matchAll
Match a digit\d (not the d flag)

How to Use the d Flag

Add d, run a match, then read indices (or indices.groups).

  1. Create a regex with the flag: /pattern/d or new RegExp("pattern", "d").
  2. Call exec, match, or (with g) matchAll.
  3. Read match.indices[n] for the full match (0) and each group.
  4. Use text.slice(start, end) to pull substrings or wrap them in markup.
PieceRequired?Role
d flagYesTurns on indices on results
Capture groupsOptionalEach group gets its own indices[n]
g flagOptionalNeeded for all matches via matchAll

Pseudocode

Pseudocode
re = /pattern/d
m = re.exec(text)

if m is null:
    no match

else:
    m[0], m[1], …           // matched text
    m.indices[0] = [s0, e0] // full match range
    m.indices[1] = [s1, e1] // group 1 range (or undefined)

    text.slice(s0, e0) === m[0]

Cheat Sheet

Keep these facts handy when working with match positions.

TopicDetail
Syntax/pattern/d or new RegExp(p, "d")
Check flagregex.hasIndices
Full match rangematch.indices[0] → [start, end)
Group nmatch.indices[n]
Named groupsmatch.indices.groups.name
All matches/pattern/gd + string.matchAll(re)
vs \dFlag = positions; \d = digit class
StandardES2022 (modern browsers / Node 16+)

Live Preview

Run a pattern with the d flag against "Code: AB-12 done" and inspect indices.

Browser demo of hasIndices — same idea as the examples below.

Result
text = "Code: AB-12 done"
/([A-Z]+)-(\d+)/d.exec(text)

m[0] = "AB-12"
indices[0] = [6, 11]
indices[1] = [6, 8]   → "AB"
indices[2] = [9, 11]  → "12"

JavaScript Examples

Short, copy-ready snippets. Open DevTools Console, or use Try It Yourself for a live editor.

Example 1 — Read Match and Group Indices

Use exec with the d flag to get [start, end) ranges.

JavaScript
const text = "Code: AB-12 done";
const re = /([A-Z]+)-(\d+)/d;
const m = re.exec(text);

console.log(m[0]);           // "AB-12"
console.log(m.indices[0]);   // [6, 11]
console.log(m.indices[1]);   // [6, 8]  → "AB"
console.log(m.indices[2]);   // [9, 11] → "12"
console.log(re.hasIndices);  // true
Try It Yourself

How It Works

  1. Enable indices. The trailing d sets hasIndices to true.
  2. Run exec. The engine finds "AB-12" starting at index 6.
  3. Parallel arrays. m[n] holds text; m.indices[n] holds the range.
  4. Half-open ranges. End is exclusive — same as slice(start, end).

Example 2 — Highlight a Match with slice

Wrap the matched span using indices[0] — no second search needed.

JavaScript
function highlight(text, re) {
  const m = re.exec(text);
  if (!m?.indices) return text;
  const [start, end] = m.indices[0];
  return text.slice(0, start) + "[" + text.slice(start, end) + "]" + text.slice(end);
}

console.log(highlight("Find the word hello here", /hello/d));
// "Find the word [hello] here"
Try It Yourself

How It Works

  1. Match once. exec returns text and indices together.
  2. Guard missing indices. Without d (or on a failed match), return the original string.
  3. Read the full-match span. indices[0] is [start, end).
  4. Rebuild with slice. Insert markers around that slice — useful for editors and search UIs.

Example 3 — Named Group Indices

Read position ranges for named captures via indices.groups.

JavaScript
const re = /(?<year>\d{4})-(?<month>\d{2})/d;
const m = re.exec("Event on 2026-07-17");

console.log(m.groups.year);                 // "2026"
console.log(m.indices.groups.year);         // [9, 13]
console.log(m.groups.month);                // "07"
console.log(m.indices.groups.month);        // [14, 16]
Try It Yourself

How It Works

  1. Name the groups. (?<year>…) and (?<month>…) fill m.groups.
  2. Add the d flag. Ranges appear in m.indices.groups under the same names.
  3. Values vs positions. groups holds text; indices.groups holds [start, end).
  4. Style parts differently. Handy when year and month need different UI treatment.

Edge Cases & Pitfalls

Check these before relying on indices in real projects.

confusion

d flag ≠ \d digits

The flag records positions. \d matches a digit inside the pattern.

optional

Skipped groups are undefined

If an optional group does not participate, indices[n] is undefined — not [0, 0].

support

Needs ES2022

Older runtimes may omit indices. Feature-detect with regex.hasIndices or "indices" in (match || {}).

global

All matches need g too

Use /…/gd with matchAll (or a loop on exec) when you want indices for every occurrence.

Browser & Runtime Support

The d (hasIndices) flag is part of ES2022. Evergreen browsers shipped it in 2021; Node.js added it in version 16.

✓ Baseline · ES2022

RegExp d / hasIndices

Supported in Chrome 90+, Firefox 88+, Safari 15+, Edge 90+, and Node 16+. Not available in Internet Explorer.

95% Modern browser support
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
d flag Excellent

Bottom line: Safe for modern web apps and current Node LTS. Feature-detect with if (regex.hasIndices) or check for match.indices before use on older targets.

Performance Notes

ApproachCostBest for
/…/d + indices~same as matchEditors, highlighters, precise wraps
Re-indexOf each groupExtra scansAvoid — error-prone for repeats
/…/gd + matchAllO(n) over stringAll matches with positions

Recording indices is cheap compared with matching itself. Prefer d over re-searching the string for each capture when you need offsets.

Key Takeaways

  • Role: d adds indices — [start, end) for the match and each group.
  • Check: regex.hasIndices mirrors the flag.
  • Named: use indices.groups alongside groups.
  • Not digits: d ≠ \d.

One line: add d when you need exact character offsets — then slice with indices instead of re-searching.

Frequently Asked Questions

The d flag (hasIndices) adds an indices property to match results. Each entry is a [start, end) pair showing where the full match and each capture group appear in the original string.
No. The d flag records match positions. The \d metacharacter matches a digit. The flag goes after the pattern (/…/d); \d goes inside the pattern.
Add d to the flags: /pattern/d, /pattern/gd, or new RegExp('pattern', 'd'). Then regex.hasIndices is true and match results include indices.
indices is parallel to the match array. indices[0] is the full match, indices[1] is group 1, and so on. Each value is [start, end) — the same half-open range as String.slice — or undefined if a group did not participate.
Not for a single match. Use d alone with exec() or match(). Combine gd when you want indices for every match via matchAll() or a repeated exec() loop.
hasIndices is ES2022. It works in Chrome 90+, Firefox 88+, Safari 15+, Edge 90+, and Node.js 16+. Feature-detect with regex.hasIndices or check for match.indices.

Next: g modifier

Learn the global flag for finding every match in a string.

g modifier 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.

10 people found this page helpful