Почему replace так работает в js?

Есть код:

let str = '2221113';

let reg = /(01|10)*/g;

let newStr = str.replace(reg, '&');

console.log(newStr);

Вопрос: Почему такой вывод? Перед каждым символом в строке есть пустой символ \u0000, который разделяет символы в строке, но мы их не видим? Поэтому срабатывает регулярное выражение: 0 или более повторений последовательности 01 или 10 и происходит замена этой пустоты на &???


Ответы (1 шт):

Автор решения: EzioMercer

Давайте рассмотрим более простой пример:

console.log('12345678'.replace(/()/g, '<>'));

Символы () между двумя символами / вставлено только потому что иначе это будет рассматриваться как начало комментария в JS. Чтобы убедиться можете перейти по ссылке, перейти во вкладку Replace и ввести в поле <> и увидеть тот же результат: https://regexr.com/6kfl5.

Как можно увидеть с таким регулярным выражением метод replace тоже вставялет <> в начале, в конце и между символами. В данном случае он ищет строку длиной 0 в заданной строке, а он по сути везде, ведь я могу спокойно представить эту строчку как:

'' + '1' + '' + '2' + '' + '3' + '' + '4' + '' + '5' + '' + '6' + '' + '7' + '' + '8' + ''

Т.е. там нет скрытых симовлов каких-то, а дело в том что именно он ищет. Строка длиной 0 по сути везде, мы можем даже это увидеть поставив пробелы:

console.log(' 12345678 '.replace(/()/g, '<>'));

Естсественным образом возникает желание сказать, что ведь строку можно представить не только в том варианте что я предложил, а с произвольным кол-ом строк длиной 0, но тут насколько я понимаю выбирается меньшее из зол, ведь в ином случае была бы бесконечная вставка. Что интересно, если перейти по ссылке, то можно сразу увидеть Error, который говорит о том что время выполнения занимает больше чем 250мс, что скорее всего связано как раз с бесконечным совпадением. А потом перейдя во вкладку Replace и введя в поле <> увидим Warning, где нас предупреждают, что в некоторых случаях наше регулярное выражение может выбрать бесконечное кол-во

→ Ссылка