Trace the fixed program
Test markup twice with /^[a-z]+$/g, reset lastIndex, and test again. The input is identical; the regular expression state is not.
const pattern=/^[a-z]+$/g;const results=[];
results.push(pattern.test('markup'));results.push(pattern.test('markup'));
pattern.lastIndex=0;results.push(pattern.test('markup'));
console.log(JSON.stringify(results));
[true,false,true]| Test | Boolean result | lastIndex afterward |
|---|---|---|
| first markup | true | 6 |
| second markup | false | 0 |
| Reset, then markup | true | 6 |
Explain the result
A global regex starts its search at lastIndex and advances it on success. The second anchored test starts at 6 and fails; failure resets it to 0. For this fixed whole-string validator, dropping g gives repeated stateless tests. Sticky expressions also use lastIndex, but their search rules differ.
Test the alternative
The global pattern is a poor repeated stateless validator here. The nonglobal repaired version accepts the same valid string twice. It still rejects the supplied uppercase boundary.
const pattern=/^[a-z]+$/;console.log(JSON.stringify([pattern.test('markup'),pattern.test('markup'),pattern.test('Markup')]));
[true,true,false]Work the boundary case
Does setting lastIndex=0 change what characters the pattern accepts?
Show the worked answer
No. It changes the start position. The fixed pattern still requires one or more lowercase ASCII letters and no other characters.
const pattern=/^[a-z]+$/g;const trace=[];for(const value of ['markup','markup','']){trace.push({value,ok:pattern.test(value),lastIndex:pattern.lastIndex});}
console.log(JSON.stringify(trace));
[{"value":"markup","ok":true,"lastIndex":6},{"value":"markup","ok":false,"lastIndex":0},{"value":"","ok":false,"lastIndex":0}]