The bug is that the regex has the g flag, so batDetector keeps its lastIndex between sections.
After the first section finishes, lastIndex is already at the end of that string. When exec() is called on the next section, it starts from that old index and can miss matches.
The simple fix is to reset lastIndex before processing each section:
for (const section of caveSections) {
batDetector.lastIndex = 0;
const batMatches = [];
let match;
while ((match = batDetector.exec(section)) !== null) {
batMatches.push(match.index);
}
// ...
}
Spot the Bug answer: The regular expression’s lastIndex property is not reset for each new section.
The fix:
Reset batDetector.lastIndex = 0; at the beginning of each loop iteration for ‘section’.
Why:
When a global regular expression is used in a loop with ‘exec’, its ‘lastIndex’ property updates after each successful match. If the same regex instance is used for multiple strings without resetting ‘lastIndex’, it will start searching from the previous ‘lastIndex’ value, potentially missing matches in subsequent strings or sections.
Hmm, yes, the lastIndex property is a classic source of subtle bugs with global regex. It’s like a musician starting a new piece but still in the middle of the previous one.
Look. I’ve seen this exact thing with logs where the parser just keeps going from the last match. You end up missing critical errors because it skipped ahead.