Заменить часть строки, подставив значение из объекта

Есть строка с текстом, которая внутри содержит короткое название эмодзи. (Эмодзи приходит из Слака в виде :clap:).

const text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry :slightly_smiling_face: Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book :clap:";

Как мне заменить эти короткие названия, на unicode эмодзи и вывести новую строку?

Отдельно имеется объект, где ключи - это короткое название без символов : (двоеточие) по бокам, а значения - соответствующий unicode. Кратко он выглядит так.

const emojis = {
    "slightly_smiling_face": "🙂",
    "clap": "👏",
    ...
}

Попробовал использовать регулярные выражения, для поиска строк, и заменой на unicode.

const regex = /:([\s]+?):/gm;

let newText;

if (text.match(regex)) {
    text.match(regex).forEach((el) => {
        for(let key in emojis) {
            if (el === `:${key}:`) {
                console.log(key,":", emojis[key]);
                newText = text.replace(regex, emojis[key])
            }
        }
    })
}

Но заменилось все на одинаковый unicode для clap.

Lorem Ipsum is simply dummy text of the printing and typesetting industry 👏 Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book 👏

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

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

Не совсем разбираюсь в данных вещах, но ваше регулярное выражение видимо не подходило для захвата нужных символов.
/:([\s]+?):/gm - захватит подстроку : : так как символ \s - включает в себя любой пробельный символ, в данном случае в группу 1 попадут просто один и более пробелов.

/:[a-zA-Z_]+:/gm - первые скобки это позитивный просмотр назад, проверяет что перед текстом есть символ :, далее в квадратных скобках перечислены диапазоны латинских букв в верхнем и нижнем регистре, а так же знак подчеркивания _, квантификатор + устанавливает что количество совпадений будет один и более, вторые круглые скобки это позитивный просмотр вперед проверяющий наличие : в конце

//переменная переведена из const в var
var text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry :slightly_smiling_face: Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book :clap:";

const regex = /(?<=:)[a-zA-Z_]+(?=:)/gm;
const emojis = {
    "slightly_smiling_face": "&#x1F642;",
    "clap": "&#x1F44F;",
}

if (text.match(regex)) {
    text.match(regex).forEach((el) => {
        for(let key in emojis) {
            if (el === key) {
                console.log(key,":", emojis[key]);
//Строкой ниже менялся весь полученный массив regex на последнюю эмодзи из цикла
//так же newText переменная была убрана, так как изменения в цикле не применялись а в newText сохранялось только последнее
                text = text.replace(`:${key}:`, emojis[key])
            }
        }
    })
}
console.log(text);


Так же уточню, что в js не разбираюсь, внес только логические исправления в код.

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

Вот 2 варианта. Какой из них лучше подойдет вам, выбирайте сами. Ну и производительность и трудоемкость этих функций не сравнивал.

const text = "Lorem Ipsum is simply dummy text of the printing :slightly_smiling_face: and typesetting industry :slightly_smiling_face: Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book :clap:";
const emojis = {
  "slightly_smiling_face": "&#x1F642;",
  "clap": "&#x1F44F;",
}

const regex = /:[a-zA-Z_]+:/gm;


function replacerEmojis() {
  let finds = text.match(regex);
  if (finds) {
    let newText = text;
    finds = finds.map(item => item.replace(/:/g, ''));
    const keys = new Set(finds);
    keys.forEach((item) => {
      const rep = new RegExp(`:${item}:`, 'g');
      newText = newText.replace(rep, emojis[item])
    });
    return newText;
  }
  return text;
}

function replacerEmojisFor() {
  let finds = text.match(regex);
  if (finds) {
    let newText = text;
    finds = finds.map(item => item.replace(/:/g, ''))
    finds.forEach(item => {
      newText = newText.replace(`:${item}:`, emojis[item])
    })
    return newText;
  }
  return text;
}

console.log('RES1', replacerEmojis())
console.log('RES2', replacerEmojisFor())

// Если есть возможность, то можно заменить справочник эмоций 
// и уйти от постоянного преобразования ':' в функциях замены

function replaceEmojiKey() {
  for (let key in emojis) {
    let keyNew = `:${key}:`;
    emojis[keyNew] = emojis[key];
    delete emojis[key];
  }
}
replaceEmojiKey();

function replacerEmojisFor2() {
  let finds = text.match(regex);
  if (finds) {
    let newText = text;
    finds.forEach(item => {
      newText = newText.replace(item, emojis[item])
    })
    return newText;
  }
  return text;
}

console.log('RES3', replacerEmojisFor2())

→ Ссылка