Ошибка при замене спец.символов

Есть код, который отлично отрабатывает, если в объекте с перечнем подлежащих замене символов не добавлять "специальные". Пример ниже вернет, как и задумано: front%end.

let sortArr = {
  " ": "-",
  "-": "%",
  "!": "i33",
};
                
let str = 'front-end'


let re = new RegExp(Object.keys(sortArr).join("|"),"gi");
    str = str.replace(re, function(matched) {
        console.log('matched ', matched);
        return sortArr[matched.toLowerCase()];
    });
    
alert(str);

Тот же пример, но добавим, например, $:

let sortArr = {
  " ": "-",
  "-": "%",
  "!": "i33",
  "$": "i36",
};
                
let str = 'front-end'


let re = new RegExp(Object.keys(sortArr).join("|"),"gi");
    str = str.replace(re, function(matched) {
        console.log('matched ', matched);
        return sortArr[matched.toLowerCase()];
    });
    
alert(str);

Результат: front%endundefined. Что я делаю не так? Ссылка на песочницу здесь.


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

Автор решения: Arseni Mourzenko

В regular expressions, символ доллара, это специальный символ, который обозначает конец текста.

Чтобы искать сам знак доллара в тексте, нужно его «escape», то есть вместо «$» использовать «\$».

→ Ссылка
Автор решения: OPTIMUS PRIME

$ - специальный знак "конец строки". Вот он у вас и пытается заменить конец строки через... matched, который уже не является символом $

Первая попытка \\$, уже получается исключить подмену конца строки, но не прокатывает, если нужно реально заменить знак $:

let sortArr = {
  " ": "-",
  "-": "%",
  "!": "i33",
  "\\$": "i36",
};

let str = 'front end $$';

let re = new RegExp( Object.keys(sortArr).join("|"), "gi");
str = str.replace(re, function(matched) {
  console.log('matched ', matched);
  return sortArr[matched.toLowerCase()];
});

console.log(str);

Попытка 2: в строке для RegExp, перед всеми спец-симвлами подставить \:
.replace(/(\$|\?|\+)/g, "\\$1") — в replace, в заменяемой строке $1 ссылается на совпадение внутри первой группы захвата (то, что внутри скобок).

let sortArr = {
  " ": "-",
  "-": "%",
  "!": "i33",
  "$": "i36",
  "?": "999",
  "|": "Mooo...",
  "+": "+++",
};

let str = '||front end $$?+';

let keys = Object.keys(sortArr).join("|")
            .replace(/(\$|\?|\+)/g, "\\$1")
            .replace(/(^|\|)\|(\||$)/, "$1\\|$2");
            
let reg = new RegExp(keys, "gi");

console.log(reg);

str = str.replace(reg, function(match) {
  return sortArr[match];
});

console.log(str);

→ Ссылка