JS replaceAll and matchAll Usage Guide

A hands-on demo of literal replacement, regular-expression pitfalls, empty-string matches, captured groups, global flags, and iterator behavior.

1. replace Highlights Only the First Match

Code:
const name = '张鑫鑫';
const highlighted = name.replace('鑫', '<mark>鑫</mark>');

document.querySelector('#replace-first-output').innerHTML = highlighted;
Result:

2. RegExp Replacement Handles All Matches, But User Input Becomes Pattern Syntax

Code:
const text = document.querySelector('#regex-text').value;
const keyword = document.querySelector('#regex-keyword').value;

try {
  const highlighted = text.replace(new RegExp(keyword, 'g'), '<mark>$&</mark>');
  document.querySelector('#regex-output').classList.remove('error');
  document.querySelector('#regex-output').innerHTML = highlighted;
} catch (error) {
  document.querySelector('#regex-output').classList.add('error');
  document.querySelector('#regex-output').textContent = error.name + ': ' + error.message;
}
Result:

3. replaceAll Replaces Every Literal Match

Code:
const text = document.querySelector('#replace-all-text').value;
const keyword = document.querySelector('#replace-all-keyword').value;
const highlighted = text.replaceAll(keyword, '<mark>' + keyword + '</mark>');

document.querySelector('#replace-all-output').innerHTML = highlighted;
Result:

4. replaceAll With RegExp Requires the Global Flag

Code:
try {
  const result = 'hello world'.replaceAll(/\s/, '');
  document.querySelector('#replaceall-regex-output').classList.remove('error');
  document.querySelector('#replaceall-regex-output').textContent = result;
} catch (error) {
  document.querySelector('#replaceall-regex-output').classList.add('error');
  document.querySelector('#replaceall-regex-output').textContent = error.name + ': ' + error.message;
}
Result:

5. replaceAll Can Match Empty Strings

Code:
const text = document.querySelector('#empty-text').value;
const pattern = document.querySelector('#empty-pattern').value;
const result = text.replaceAll(pattern, '_');

document.querySelector('#empty-string-output').textContent = result;
Result:

6. Guard Empty Search Before Highlighting

Code:
const text = document.querySelector('#guard-text').value;
const keyword = document.querySelector('#guard-keyword').value;
const output = document.querySelector('#empty-guard-output');

if (keyword === '') {
  output.textContent = text;
} else {
  output.innerHTML = text.replaceAll(keyword, '<mark>' + keyword + '</mark>');
}
Result:

7. match Ignores Captured Groups; matchAll Keeps Them

Code:
const str = document.querySelector('#match-text').value;
const reg = /\s+([a-z]+)/g;

const matchResult = str.match(reg);
const matchAllResult = Array.from(str.matchAll(reg)).map(item => ({
  fullMatch: item[0],
  capturedGroup: item[1],
  index: item.index
}));

document.querySelector('#match-groups-output').textContent = JSON.stringify({
  match: matchResult,
  matchAll: matchAllResult
}, null, 2);
Result:

8. matchAll Also Requires the Global Flag

Code:
try {
  const result = Array.from('author name'.matchAll(/\s+([a-z]+)/));
  document.querySelector('#matchall-global-output').classList.remove('error');
  document.querySelector('#matchall-global-output').textContent = JSON.stringify(result, null, 2);
} catch (error) {
  document.querySelector('#matchall-global-output').classList.add('error');
  document.querySelector('#matchall-global-output').textContent = error.name + ': ' + error.message;
}
Result:

9. No Match: match Returns null, matchAll Returns an Empty Array After Conversion

Code:
const text = document.querySelector('#no-match-text').value;
const reg = /xyz/g;

const matchValue = text.match(reg);
const matchAllValue = Array.from(text.matchAll(reg));

document.querySelector('#no-match-output').textContent = JSON.stringify({
  match: matchValue,
  matchAll: matchAllValue
}, null, 2);
Result:

10. matchAll Uses an Iterator and Does Not Mutate the Original RegExp lastIndex

Code:
const str = 'one two three';
const reg = /\w+/g;

reg.lastIndex = 4;

const matches = Array.from(str.matchAll(reg)).map(item => item[0]);

document.querySelector('#lastindex-output').textContent = JSON.stringify({
  matches: matches,
  lastIndexAfterMatchAll: reg.lastIndex
}, null, 2);
Result:

11. Browser Support Check

Code:
const support = {
  replaceAll: typeof ''.replaceAll === 'function',
  matchAll: typeof ''.matchAll === 'function'
};

document.querySelector('#support-check-output').innerHTML =
  '<div class="cards">' +
    '<div class="mini-card"><strong>replaceAll</strong>' +
      '<span class="' + (support.replaceAll ? 'status-yes' : 'status-no') + '">' +
        (support.replaceAll ? 'Supported' : 'Not supported') +
      '</span></div>' +
    '<div class="mini-card"><strong>matchAll</strong>' +
      '<span class="' + (support.matchAll ? 'status-yes' : 'status-no') + '">' +
        (support.matchAll ? 'Supported' : 'Not supported') +
      '</span></div>' +
  '</div>';
Result: