В поисках смайликов в строках - PullRequest
0 голосов
/ 14 апреля 2020

Так что я пытаюсь найти и заменить эмодзи в строках. Пока что это мой подход к регулярному выражению.

const replaceEmojis = function (string) {
    String.prototype.regexIndexOf = function (regex, startpos) {
        const indexOf = this.substring(startpos || 0).search(regex);
        return (indexOf >= 0) ? (indexOf + (startpos || 0)) : indexOf;
    }
    // generate regexp
    let regexp;
    try {
        regexp = new RegExp('\\p{Emoji}', "gu");
    } catch (e) {
        //4 firefox <3
        regexp = new RegExp(`(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])`, 'g');
    }

    // get indices of all emojis
    function getIndicesOf(searchStr, str) {
        let index, indices = [];

        function getIndex(startIndex) {
            index = str.regexIndexOf(searchStr, startIndex);
            if (index === -1) return;
            indices.push(index);
            getIndex(index + 1)
        }

        getIndex(0);

        return indices;
    }

    const emojisAt = getIndicesOf(regexp, string);

    // replace emojis with SVGs
    emojisAt.forEach(index => {
        // got nothing here yet
        // const unicode = staticHTML.charCodeAt(index); //.toString(16);
    })

Проблема в том, что я получаю массив только с индексами, где смайлики находятся в строке. Но только с этими индексами я не могу заменить их, потому что я не знаю, сколько байтов (UTF-16) они занимают. Также для их замены мне нужно знать, какие именно эмодзи я заменяю.

Итак, есть ли способ также определить длину эмодзи? Или есть лучший (возможно, более простой) способ, чем мой, заменить смайлики?

Ответы [ 2 ]

0 голосов
/ 15 апреля 2020

Хорошо, так получается, у меня только что был небольшой психический блок.
Чтобы найти смайлики, мне не нужно получать индексы, как упомянуто WolverinDEV . Хотя использование string.replace с /\p{Emoji}/gu не работает, так как это разбивает, например, на ??‍♂️, ? и ♂. Поэтому я настроил регулярное выражение для учета этого: /[\p{Emoji}\u200d]+/gu. Теперь смайлики возвращаются полностью, потому что включены столяр нулевой ширины.
Это то, что я получил (если кому-то все равно):

const replaceEmojis = function (string) {
    const emojis = string.match(/[\p{Emoji}\u200d]+/gu);
    // console.log(emojis);

    // replace emojis with SVGs
    emojis.forEach(emoji => {
        // get the unicodes of the emoji
        let unicode = "";

        function getNextChar(pointer) {
            const subUnicode = emoji.codePointAt(pointer);
            if (!subUnicode) return;
            unicode += '-' + subUnicode.toString(16);
            getNextChar(++pointer);
        }

        getNextChar(0);

        unicode = unicode.substr(1); // remove the beginning dash '-'
        console.log(unicode.toUpperCase());

        // replace emoji here
        // string = string.replace(emoji, `<svg src='path/to/svg/${unicode}.svg'>`)
    })

    return string;
}

Это все еще требует работы, например, из-за Низкий Суррогаты в выводимом юникоде, но, по сути, это работает.

РЕДАКТИРОВАТЬ:

Первое улучшение:
Возможно, вам это не нужно избавиться от суррогатных символов с низким добавлением добавить условие в getNextChar()

if (!(subUnicode >= 56320 && subUnicode <= 57343)) unicode += '-' + subUnicode.toString(16);

Добавляет код символа, только если он не является суррогатным символом с низким уровнем.

Второе улучшение:
Добавьте селектор вариантов 16 (U + FE0F) к регулярному выражению, чтобы выбрать больше emojis en blo c:

/[\p{Emoji}\u200d\ufe0f]+/gu
0 голосов
/ 15 апреля 2020

Ну, у вас уже есть работающий RegExp, поэтому вы можете использовать String.replace:

string.replace(regexp, my_emojy => { 
    return "<an emoji was here>";
});

Так что вам вообще не нужно искать индексы.

...