Johnny Johnny - 10 months ago 47
Javascript Question

Exclude array of words from regex match in Javascript

I am given two variables, a string [var str] and an array of words [var exceptions]. I am replacing every middle character of every word longer than 3 letters with an asterisk using the following regular expression:

var edited = str.replace(/\B\w\B/g, '*');

For example, the string "This is an example of what I am doing" would be returned as "T**s is an e*****e of w**t I am d***g".

However, I would like to add exceptions to this regular expression. So for example, I am given the array (
var exceptions = ["example","doing"]
), then I would like the regex to return: "T**s is an example of w**t I am doing"

Does anyone know how to do this? If there is a way to achieve this using regex great, if not I am open to other suggestions.

Many thanks :)


I'd probably turn the array of excludes into a map so that I benefit from faster checking if a word is in the array. Then I'd use the fact that the replace function accepts a function for the replacement, and make the decision in there:

var exclude = ["example", "what"];
var str = "This is an example of what I am doing";

var map = Object.create(null);
exclude.forEach(function(entry) {
  map[entry] = true;
var edited = str.replace(/\b(\w)(\w+)(\w)\b/g, function(m, c0, c1, c2) {
  return map[m] ? m : c0 + "*".repeat(c1.length) + c2;

I've used String#repeat in the above, which is from ES2015, but can be easily shimmed for older browsers. Or use c1.replace(/./g, "*") instead.

Here's an ES2015+ version, using Set rather than an object map:

let exclude = ["example", "what"];
let str = "This is an example of what I am doing";

let set = new Set();
exclude.forEach(entry => {
let edited = str.replace(/\b(\w)(\w+)(\w)\b/g, (m, c0, c1, c2) =>
  set.has(m) ? m : c0 + "*".repeat(c1.length) + c2