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
Add d, run a match, then read indices (or indices.groups).
Create a regex with the flag: /pattern/d or new RegExp("pattern", "d").
Call exec, match, or (with g) matchAll.
Read match.indices[n] for the full match (0) and each group.
Use text.slice(start, end) to pull substrings or wrap them in markup.
Piece
Required?
Role
d flag
Yes
Turns on indices on results
Capture groups
Optional
Each group gets its own indices[n]
g flag
Optional
Needed 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]
Reference
Cheat Sheet
Keep these facts handy when working with match positions.
Topic
Detail
Syntax
/pattern/d or new RegExp(p, "d")
Check flag
regex.hasIndices
Full match range
match.indices[0] → [start, end)
Group n
match.indices[n]
Named groups
match.indices.groups.name
All matches
/pattern/gd + string.matchAll(re)
vs \d
Flag = positions; \d = digit class
Standard
ES2022 (modern browsers / Node 16+)
Try it
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.
Name the groups.(?<year>…) and (?<month>…) fill m.groups.
Add the d flag. Ranges appear in m.indices.groups under the same names.
Values vs positions.groups holds text; indices.groups holds [start, end).
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.
Compatibility
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 ChromeSupported · Desktop & Mobile
Full support
Mozilla FirefoxSupported · Desktop & Mobile
Full support
Apple SafariSupported · macOS & iOS
Full support
Microsoft EdgeSupported · Chromium
Full support
Internet ExplorerNo native support · Use a polyfill
Polyfill
OperaSupported · Modern versions
Full support
Samsung InternetSupported · Android
Full support
BunSupported · JavaScript runtime
Supported
DenoSupported · JavaScript runtime
Supported
Node.jsSupported · Server runtime
Supported
Android WebViewSupported · Modern WebView
Full support
d flagExcellent
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.
Analysis
Performance Notes
Approach
Cost
Best for
/…/d + indices
~same as match
Editors, highlighters, precise wraps
Re-indexOf each group
Extra scans
Avoid — error-prone for repeats
/…/gd + matchAll
O(n) over string
All 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.
Remember
Key Takeaways
Role:d adds indices — [start, end) for the match and each group.
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.