查找和替换为字典,仅使用键一次

Pen*_*ume 1 javascript regex search dictionary replace

这是在词典查找多个关键字的后续操作。

我的问题是...

  1. 第一个是:我相信这会匹配不完整的单词。就像我的词典中的short一样,它很快就会与单词匹配。我将如何停止呢?

  2. 第二个不是那么重要,但很好的是:我将如何制作它,以便每个内容仅匹配一次?如此短就不会在同一内容区域内被定义两次。

谢谢!

Rob*_*b W 5

我已经实现了以下附加要求:

  • shortly查找时不匹配short(因为shortly是另一个词)
  • 仅在字典中使用键一次。
    输入示例:key = foo,replacement = bar,content = foo foo
    输出:(bar foofoo替换第一个)。

演示:http//jsfiddle.net/bhGE3/3/

用法:

  1. 定义一个dictionary。每个密钥只能使用一次。
  2. 定义content。将基于该字符串创建一个新字符串。
  3. (可选)定义一个replacehandler函数。每次比赛都调用此函数。返回值将用于替换匹配的词组。
    默认值replacehandler将返回字典的匹配短语。该函数应带有两个参数:keydictionary
  4. 呼叫 replaceOnceUsingDictionary(dictionary, content, replacehandler)
  5. 处理输出,例如 content向用户展示。

码:

var dictionary = {
    "history": "war . ",
    "no": "in a",
    "nothing": "",
    "oops": "",
    "time": "while",
    "there": "We",
    "upon": "in",
    "was": "get involved"
};
var content = "Once upon a time... There was no history. Nothing. Oops";
content = replaceOnceUsingDictionary(dictionary, content, function(key, dictionary){
    return '_' + dictionary[key] + '_';
});
alert(content);
// End of implementation

/*
* @name        replaceOnceUsingDictionary
* @author      Rob W http://stackoverflow.com/users/938089/rob-w
* @description Replaces phrases in a string, based on keys in a given dictionary.
*               Each key is used only once, and the replacements are case-insensitive
* @param       Object dictionary  {key: phrase, ...}
* @param       String content
* @param       Function replacehandler
* @returns     Modified string
*/
function replaceOnceUsingDictionary(dictionary, content, replacehandler) {
    if (typeof replacehandler != "function") {
        // Default replacehandler function.
        replacehandler = function(key, dictionary){
            return dictionary[key];
        }
    }

    var patterns = [], // \b is used to mark boundaries "foo" doesn't match food
        patternHash = {},
        oldkey, key, index = 0,
        output = [];
    for (key in dictionary) {
        // Case-insensitivity:
        key = (oldkey = key).toLowerCase();
        dictionary[key] = dictionary[oldkey];

        // Sanitize the key, and push it in the list
        patterns.push('\\b(?:' + key.replace(/([[^$.|?*+(){}])/g, '\\$1') + ')\\b');

        // Add entry to hash variable, for an optimized backtracking at the next loop
        patternHash[key] = index++;
    }
    var pattern = new RegExp(patterns.join('|'), 'gi'),
        lastIndex = 0;

    // We should actually test using !== null, but for foolproofness,
    //  we also reject empty strings
    while (key = pattern.exec(content)) {
        // Case-insensitivity
        key = key[0].toLowerCase();

        // Add to output buffer
        output.push(content.substring(lastIndex, pattern.lastIndex - key.length));
        // The next line is the actual replacement method
        output.push(replacehandler(key, dictionary));

        // Update lastIndex variable
        lastIndex = pattern.lastIndex;

        // Don't match again by removing the matched word, create new pattern
        patterns[patternHash[key]] = '^';
        pattern = new RegExp(patterns.join('|'), 'gi');

        // IMPORTANT: Update lastIndex property. Otherwise, enjoy an infinite loop
        pattern.lastIndex = lastIndex;
    }
    output.push(content.substring(lastIndex, content.length));
    return output.join('');
}
Run Code Online (Sandbox Code Playgroud)