Почему первый символ после подпрограммы каким-то образом игнорируется в регулярном выражении?

Вот что я получил в консоли Chrome 78.

console.log('1111'.replace(/(^|[^2])/g, '$12'))
// output "21121212"

Почему он не заменяет первый 1 на 12?


person pansila    schedule 14.11.2019    source источник
comment
Какой результат вы ожидали? $1 — это ссылка на захваченное совпадение.   -  person ggorlen    schedule 14.11.2019
comment
Я думаю, что желаемый результат - 212121212.   -  person yqlim    schedule 14.11.2019
comment
@YongQuan Да, я тоже так думал, но я проверил код OP, и на самом деле результат 21121212.   -  person Tim Biegeleisen    schedule 14.11.2019
comment
Это известная проблема, когда регулярное выражение JS пропускает текущую позицию после совпадения нулевой длины, см. связанный поток с подробным объяснением основной причины.   -  person Wiktor Stribiżew    schedule 14.11.2019


Ответы (2)


Я думаю, что происходит то, что после замены совпадения нулевой ширины он увеличивает позицию во входной строке на 1 перед поиском следующего совпадения. В противном случае он застрял бы в бесконечном цикле, постоянно сопоставляя и заменяя одну и ту же строку нулевой ширины.

Поскольку ^ соответствует строке нулевой ширины в начале, она увеличивает позицию, пропуская первый символ строки перед поиском следующего совпадения.

person Barmar    schedule 14.11.2019

Способ 1

Я предполагаю, что вы пытаетесь написать

(?<=^)|([^2])

тем не менее, вы хотели бы проверить, поддерживаются ли обходные пути или нет.

Демонстрация 1


Способ 2

Этот метод также имеет обходные пути,

(?<=^|[^2])

Демонстрация 2

Если вы предоставите несколько примеров входных и выходных данных, могут быть некоторые обходные пути.

Например, возможно, положительный прогноз может быть вариантом для изучения:

(?=^|[^2]|$)

Демонстрация 3


Если вы хотите упростить/изменить/исследовать выражение, это объяснено на верхней правой панели regex101. ком. Если хотите, вы также можете посмотреть по этой ссылке, как она будет соответствовать против некоторых выборочных входных данных.


Цепь регулярных выражений

jex.im визуализирует обычные выражения:

введите здесь описание изображения

person Emma    schedule 14.11.2019
comment
Ваша демонстрация не работает, если вы переключитесь с PCRE на ECMAScript. - person Barmar; 14.11.2019
comment
К сожалению, ECMAScript не поддерживает просмотр назад. - person yqlim; 14.11.2019