admin管理员组文章数量:1335887
This is a follow-up of Find multiple keywords within a dictionary.
My questions are...
The first is: I believe this matches words that are not whole. Like if short is in my dictionary it matches the word shortly. How would I stop this?
And the second not so important but would be nice is: How would I make it so it only matches once per content? So short doesn't get defined twice within the same content area.
Thanks!
This is a follow-up of Find multiple keywords within a dictionary.
My questions are...
The first is: I believe this matches words that are not whole. Like if short is in my dictionary it matches the word shortly. How would I stop this?
And the second not so important but would be nice is: How would I make it so it only matches once per content? So short doesn't get defined twice within the same content area.
Thanks!
Share Improve this question edited May 23, 2017 at 12:08 CommunityBot 11 silver badge asked Dec 29, 2011 at 19:50 PengumePengume 5701 gold badge11 silver badges27 bronze badges1 Answer
Reset to default 6I have implemented the following additional requirements:
- Do not match
shortly
when looking forshort
(becauseshortly
is a different word) - Use keys in the dictionary only once.
Example input: key=foo
, replacement=bar
, content=foo foo
.
Output:bar foo
(only the firstfoo
is replaced).
Demo: http://jsfiddle/bhGE3/3/
Usage:
- Define a
dictionary
. Each key will be used only once. - Define
content
. A new string will be created, based on this string. - Optionally, define a
replacehandler
function. This function is called at each match. The return value will be used to replace the matched phrase.
The defaultreplacehandler
will return the dictionary's matching phrase. The function should take two arguments:key
anddictionary
. - Call
replaceOnceUsingDictionary(dictionary, content, replacehandler)
- Process the output, eg. show
content
to the user.
Code:
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./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('');
}
本文标签: javascriptFind and replace by a dictionaryusing keys only onceStack Overflow
版权声明:本文标题:javascript - Find and replace by a dictionary, using keys only once - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742396616a2467052.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论