Вы можете создать регулярное выражение, которое чередуется между всеми .keys
из map
, экранируя сначала ключи, так что символы со специальным значением в регулярном выражении (например, $
) анализируются как буквенные символы , а не специальные символы регулярного выражения.
Также чередуются с шаблоном, который соответствует символу обратного удара, за которым следуют символы, не являющиеся символом обратного удара, после которого следует еще один символ обратного удара - таким образом все подстроки, заключенные в обратный знак, будут сопоставляться какну.
Вызовите .replace
для входной строки с созданным шаблоном и используйте функцию заменителя.Если совпадение начинается с обратной черты, то это то, что вы вообще не хотите изменять, поэтому просто верните совпадение.В противном случае совпадение является одним из ключей map
, поэтому верните соответствующее значение в этом ключе в map
:
const message = "this is my :) `funky :)` string with a funky `goal :D` live is good :D";
const map = {
"<3": "\u2764\uFE0F",
"</3": "\uD83D\uDC94",
":D": "\uD83D\uDE00",
":)": "\uD83D\uDE03",
":-)": "\uD83D\uDE03",
";)": "\uD83D\uDE09",
":(": "\uD83D\uDE12",
":p": "\uD83D\uDE1B",
";p": "\uD83D\uDE1C",
":'(": "\uD83D\uDE22",
":S": "\ud83d\ude1f",
":$": "\ud83d\ude33",
":@": "\ud83d\ude21"
};
const escape = str => str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
const backtickPattern = '`[^`]*`';
const pattern = new RegExp(
backtickPattern + '|' + Object.keys(map)
.map(escape)
.join('|'),
'g'
);
const output = message.replace(pattern, match => {
if (match.startsWith('`')) {
// backtick, don't perform any replacements:
return match;
}
return map[match];
});
console.log(output);