I am trying to replace words in a string with matches from an object. If a word matches the property from an object, it will be replaced by the relevant value. My problem is cases where there is a character before and after the word that should be replaced, unless the character is a whitespace or a hyphen.
function fixTypos(str) {
var typoObject = {
descriptiogn:'description',
decscription:'description',
vdescription:'description',
wdescription:'description',
descriptiog:'description',
statucs:'status',
statuqs:'status',
cstatus:'status',
for (var key in typoObject) {
str = str.replace(new RegExp(`\\b${key}\\b`, "gi"), typoObject[key]);
}
return str;
}
teststring: 'word -decscription word2 adescriptiogn word3 -astatucs'
current output: 'word -description word2 adescriptiogn word3 -astatucs'
desired output: 'word -description word2 description word3 -status'
My approach might be the wrong one, since I start to doubt it can be done via regex, but maybe someone here has an idea for me?
Edit: added more variety in the object. The object is an example, but the one I use for my project contains over 2k property:value pairs with not always matching values
CodePudding user response:
I would just use an alternation here. Create an array of description variant terms to find, and then do a global replacement.
var input = 'word -decscription word2 adescriptiogn word3 -adescriptiogn';
var terms = ['descriptiogn', 'decscription', 'vdescription', 'wdescription', 'descriptiog'];
var regex = new RegExp("\\b\\w*(?:" terms.join("|") ")\w*\\b", "g");
var output = input.replace(regex, "description");
console.log(input);
console.log(output);
CodePudding user response:
You could build one regular expression to catch any of the keywords, using a capture group to identify which it was, and a callback function to do the lookup for the translation:
const translation = {
descriptiogn:'description',
decscription:'description',
vdescription:'description',
wdescription:'description',
descriptiog:'description',
statucs:'status',
statuqs:'status',
cstatus:'status',
};
const regex = new RegExp("\\b\\w*("
Object.keys(translation)
.sort((a, b) => b.length - a.length)
.join("|")
")\w*\\b", "g");
const fixTypos = str => str.replace(regex, (_, match) => translation[match]);
const teststring= 'word -decscription word2 adescriptiogn word3 -astatucs'
console.log(fixTypos(teststring));
Sorting the keywords from longest to shortest may be necessary so to give precedence to the longer matches when also a shorter key would match.