Как заменить токены с границей слова в тексте в JavaScript - PullRequest
0 голосов
/ 31 января 2019

Для данного текста в ASCII или Unicode, я должен заменить жетоны слов на границы слов заменой.Мой подход состоял в том, чтобы искать токен с помощью регулярного выражения, которое учитывает Unicode и не-Unicode регистр - см. здесь , а затем сопоставлять вхождение этого токена итерацию по RegExp.exec.отслеживая последний увиденный токен:

/**
 * Replace tokens in text
 * It support both Unicode and ASCII Regex for word boundaries
 * @param {*} isUnicode true to use Unicode Regex
 * @param {*} text input text
 * @param {*} tokens Tokens indexes
 * @param {*} words Words
 * @param {*} expr Replacement 
 */
var replaceTokens = function (isUnicode, text, tokens, words, expr) {
    const seen = new Map();
    var pattern = "\\b($1)\\b";
    if (isUnicode) pattern = "(?<!\\S)$1(?!\\S)";
    tokens.forEach((token, index) => {
        var word = words[index];
        var escaped = word.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
        var wordRegex = new RegExp(pattern.replace('$1', escaped), "g");
        var match = null;
        while ((match = wordRegex.exec(text)) !== null) {
            if (match.index > (seen.get(word) || -1)) {
                var wordEnd = match.index + word.length - 1;
                var replacement = expr[token].replace('$1', escaped);
                text = text.slice(0, match.index) + replacement + text.slice(wordRegex.lastIndex);
                seen.set(word, wordEnd);
                break;
            }
        }
    });
    return text;
}//replaceTokens

Поэтому для его использования мне нужен исходный текст в text, массив words, массив tokens слов индексов,карта expr замен, например

text = "Hello Word"
words = ["Hello", "Word"]
tokens = ["1", "2"]
expr = { "1" : "<span style="color:blue;">$1</span>", "2": "<span style="color:red;">$1</span>"}
replaceTokens(false, text, tokens, words, expr)

или в случае Unicode:

text = "तुम मुझे दोस्त कहते कहते हो"
words = ["तुम","मुझे","दोस्त","कहते","कहते","हो"]
//...tokens and expr index
replaceTokens(true, text, tokens, words, expr)

Я не уверен, что это оптимальное решение из-за вложенных операций.Я попытался использовать String.replace и указать функцию для замены - см. здесь вместо использования вложенного RegExp.exec, но я не смог понять, как это сделать.В более простом решении мне понравилось

text = text.replace(new RegExp("\\b(" + word + ")\\b", "gi"), expr[token]);

, но этот подход не учитывает повторение слова в нескольких позициях (он заменяет все), поэтому он не работает должным образом, даже если он был более вычислительнымэффективный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...