Home > Back-end >  replace word with match from object in JS
replace word with match from object in JS

Time:12-20

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.

  • Related