0

The goal of the code below is to get all parts of the string with a special treatment for text between * ... * (ie: emboldening).

const regex = new RegExp("([^\\*]*)*\\*([^\\*]+)\\*", "g");
const string = '*A B C*D E F*G H I*J K L*M N O*P Q R*S T U*';

const matches = string.matchAll(regex);
result = 'Result => ';
for (const match of matches) {
  result += (match[1] ? match[1] : '') + (match[2] ? '<b>'+match[2]+'</b>' : '');
}
document.getElementsByTagName('body')[0].innerHTML = result;

Actually, that works fine. But if I had a simple test on the regex (regex.test(string)) before doing all the matchAll process, the result returned is not the same (skipping the begining of the string) :

const regex = new RegExp("([^\\*]*)*\\*([^\\*]+)\\*", "g");
const string = '*A B C*D E F*G H I*J K L*M N O*P Q R*S T U*';

if (regex.test(string)) {
  const matches = string.matchAll(regex);
  result = 'Result => ';
  for (const match of matches) {
    result += (match[1] ? match[1] : '') + (match[2] ? '<b>'+match[2]+'</b>' : '');
  }
  document.getElementsByTagName('body')[0].innerHTML = result;
}

I didn't found any documentation or clue on this weirdness... Is this a bug ? Or a trap and I fell inside ? Someone have any explanation ?

  • 1
    Because it moves the RegExp index due to the `g` flag. BTW, it seems `string.replace(/\*([^*]+)\*/g, '$1')` would be enough. – Wiktor Stribiżew Jul 20 '21 at 08:32
  • Global regular expressions are stateful. That's why using them more than once will cause a difference. – VLAZ Jul 20 '21 at 08:32

0 Answers0