Заменить часть строки, подставив значение из объекта
Есть строка с текстом, которая внутри содержит короткое название эмодзи. (Эмодзи приходит из Слака в виде :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 шт):
Не совсем разбираюсь в данных вещах, но ваше регулярное выражение видимо не подходило для захвата нужных символов.
/:([\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": "🙂",
"clap": "👏",
}
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 не разбираюсь, внес только логические исправления в код.
Вот 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": "🙂",
"clap": "👏",
}
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())