JS: Regex lastIndex
What is .lastIndex
.lastIndex-
A index for the target string, used by some regex functions.
this property is set automatically by regex functions, and only if the regex object has Regex Flag g (global) or Regex Flag y (sticky).
in the case of RegExp.prototype.exec and RegExp.prototype.test, the behavior is:
If a match is found,
lastIndexis set to the end position of the matched substring. If no match is found,lastIndexis set to 0.lastIndexcan be set. e.g.myRegexObj.lastIndex = 5.
Each regex object has own lastIndex
const rgx = /x/; console.log(rgx.lastIndex); // 0 console.log(Object.hasOwn(rgx, "lastIndex")); // true
Example. demo with regex.test method
// without regex flag g or flag y , lastIndex is always 0. // test with RegExp.prototype.test const xtext = "012-45-78-"; const rgx = /-/; console.assert(rgx.lastIndex === 0); console.assert(rgx.test(xtext) === true); console.assert(rgx.lastIndex === 0); console.assert(rgx.test(xtext) === true); console.assert(rgx.lastIndex === 0);
// with regex flag g, lastIndex is advanced or set to 0. // test with RegExp.prototype.test const xtext = "012-45-78-"; const rgx = /-/g; console.assert(rgx.lastIndex === 0); console.assert(rgx.test(xtext) === true); console.assert(rgx.lastIndex === 4); console.assert(rgx.test(xtext) === true); console.assert(rgx.lastIndex === 7);
// with regex flag y, lastIndex is advanced or set to 0. // test with RegExp.prototype.test const xtext = "012-45-78-"; const rgx = /-/y; rgx.lastIndex = 3; console.log(rgx.lastIndex); // 3 console.log(rgx.test(xtext)); // true console.log(rgx.lastIndex); // 4 console.log(rgx.test(xtext)); // false console.log(rgx.lastIndex); // 0
Example. demo with regex.exec method
// without regex flag g or flag y , lastIndex is always 0. const xtext = "012-45-78-"; const rgx = /-/; console.assert(rgx.lastIndex === 0); console.log(rgx.exec(xtext)); // [ "-", index: 3, input: "012-45-78-", groups: undefined ] console.assert(rgx.lastIndex === 0); console.log(rgx.exec(xtext)); // [ "-", index: 3, input: "012-45-78-", groups: undefined ] console.assert(rgx.lastIndex === 0);
// with regex flag g. lastIndex is advanced or set to 0. // test with RegExp.prototype.exec const xtext = "012-45-78-"; const rgx = /-/g; console.assert(rgx.lastIndex === 0); console.log(rgx.exec(xtext)); // [ "-", index: 3, input: "012-45-78-", groups: undefined ] console.assert(rgx.lastIndex === 4); console.log(rgx.exec(xtext)); // [ "-", index: 6, input: "012-45-78-", groups: undefined ] console.assert(rgx.lastIndex === 7); console.log(rgx.exec(xtext)); // [ "-", index: 9, input: "012-45-78-", groups: undefined ] console.assert(rgx.lastIndex === 10); console.log(rgx.exec(xtext)); // null console.assert(rgx.lastIndex === 0);
Regex functions that use lastIndex
which js regex methods use lastIndex
(ai answer)
Main ones: RegExp.prototype.exec() and RegExp.prototype.test().
These (and methods that call them) only use/update lastIndex when the regex has the g (global) or y (sticky) flag. Otherwise lastIndex is ignored.
Behavior summary
| Method | Uses / updates lastIndex? |
Notes |
|---|---|---|
regex.exec(str) |
Yes | Primary method. Advances on match, resets to 0 on failure. |
regex.test(str) |
Yes | Calls exec() under the hood. Same side effects. |
str.match(regex) |
Yes (if g) |
Repeatedly calls exec. Usually ends with lastIndex = 0. |
str.replace(regex, …) / replaceAll |
Yes (if g or y) |
Sets to 0 at start for global. Sticky (y only) can leave it changed. |
str.matchAll(regex) |
On a copy | Creates a new regex (via Symbol.species) that copies lastIndex. Original is unchanged. |
str.search(regex) |
Temporarily | Sets to 0, runs, then restores previous value. No lasting side effect. |
str.split(regex) |
On a copy | Original lastIndex is not modified. |
Key takeaway: Reusing a global/sticky regex across calls (especially test/exec) is a common source of bugs because lastIndex persists. Reset it (regex.lastIndex = 0) or create a fresh regex when needed.