Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic RegExp with case preservation in JavaScript

What I am trying to do is to write a function to replace a single word in a given sentence. One of the requirements is so that the case of the replaced word will be preserved as with the original.

I wrote the following function:

function replace(str, before, after) {
  var re = new RegExp('(\\.*)?(' + before + ')(\\.*)?', 'i');
  return str.replace(re, after);
}


// DEBUG
console.log('----- DEBUG START -----');

var tasks = [
  replace("A quick brown fox jumped over the lazy dog", "jumped", "leaped"),
  replace("Let us go to the store", "store", "mall"),
  replace("He is Sleeping on the couch", "Sleeping", "sitting"),
  replace("This has a spellngi error", "spellngi", "spelling"),
  replace("His name is Tom", "Tom", "john"),
  replace("Let us get back to more Coding", "Coding", "bonfires"),
];

for (var i = 0; i < tasks.length; i++) {
  console.log('Result #' + i + ': ' + tasks[i]);
}

console.log('----- DEBUG END -----');

Everything works fine, beside the fact that the case of the after word is not the same as the case of the before word.

INFO:

I solved the same problem using arrays (using split(), splice(), indexOf() ) and replacing only the before element with a non-dynamic RegExp() and the case was preserved. This is why I don't quite understand why my other solution does not work.

like image 700
bx2 Avatar asked Oct 19 '22 06:10

bx2


1 Answers

You are replacing a string of characters with another string of characters. JS won't magically apply the capitalization of the original word to the replacement word as this could lead to potentially unwanted behaviour. If you have to preserve the cases of characters, you need to go out of your way to do it.

If you only care about the capitalization of the first letter, you can do the following in the replace function:

function replace(str, before, after) {
  var b0 = before[0];
  after = after.replace(/^(.)/, function(a0){
    return b0.toUpperCase() === b0 ? a0.toUpperCase() : a0.toLowerCase();
  });
  var re = new RegExp('(\\.*)?(' + before + ')(\\.*)?', 'i');
  return str.replace(re, after);
}

// DEBUG
document.write('----- DEBUG START -----<br>');

var tasks = [
  replace("A quick brown fox jumped over the lazy dog", "jumped", "leaped"),
  replace("Let us go to the store", "store", "mall"),
  replace("He is Sleeping on the couch", "Sleeping", "sitting"),
  replace("This has a spellngi error", "spellngi", "spelling"),
  replace("His name is Tom", "Tom", "john"),
  replace("Let us get back to more Coding", "Coding", "bonfires"),
];

  for (var i = 0; i < tasks.length; i++) {
  document.write('Result #' + i + ': ' + tasks[i]+'<br>');
}

document.write('----- DEBUG END -----');
like image 104
SeinopSys Avatar answered Oct 30 '22 20:10

SeinopSys