Кажется, вы смешиваете экранирование обратной косой черты.
Вам необходимо избегать обратной косой черты в строковых литералах, потому что обратная косая черта используется также для экранирования других символов.Это означает, что строка литерал '\\'
хранится как \
, как вы можете видеть здесь:
console.log('\\');
В регулярном выражении вам также нужно экранировать символы с одним обратным слешем, но если вы делаете это в строковом литерале, вам нужно дважды экранировать их по вышеуказанной причине.Вот почему ваш рабочий пример работает.Но в вашей функции escape()
вы добавляете две обратных косых черты вместо одной.Просто измените '\\\\$&'
на '\\$&'
, и оно должно работать нормально.
function escape(str) {
return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}
function replace(str, needle, replacement) {
var expr = '([^\\[]*)(' +
escape(needle) + ')([^\\]]*)';
return str.replace(new RegExp(expr, 'g'), '$1' + replacement + '$3');
}
console.log(replace('hello() [hello()] test()', '()', '@'));