Raul
Raul

Reputation: 3081

Javascript Regex - Undetermined number of vowels in a word

I have a really long list of words blacklist = ["sandwhich", "banana", "cheese"...] and I am implementing a system to check if a text doesn't includes those words as substrings.

What I am doing is:

  /*
   * Determine if a given text contains invalid words
   * @param {string} text
   **/
  isInvalid(text) {
    return (
      this.blacklist.filter((word) => new RegExp(word, "i").test(text)).length >
      0
    );
  }

So, if I test the method with:

  myFilter.isInvalid("I love bananas")

it returns true.

But, if I try with:

  myFilter.isInvalid("I love banaaaaaanaaas"); // <- Multiple vowels

it returns false... and I need a true.

Is there any way to achieve this?

Thank you.

Upvotes: 0

Views: 103

Answers (2)

Peter Seliger
Peter Seliger

Reputation: 13377

The most straightforward approach might be creating a regex (from each blacklisted word) which recognizes any vowel within such a word and rewrites each vowel in a way that within a regex pattern this very vowel will be searched as either once or many and also can be consumed by an RegExp function ...

console.log(
  'bananas'.replace((/[aeiou]/ig), (match => `${ match }+`))
);
console.log(
  RegExp('bananas'.replace((/[aeiou]/ig), (match => `${ match }+`)), 'i')
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

... a method which implements the above then might be named createVowelSequenceRegex and used accordingly by the already existing validation method (isInvalid) ...

function createVowelSequenceRegex(text) {
  return RegExp(text.replace((/[aeiou]/ig), (match => `${ match }+`)), 'i');
}
const sampleText = 'I love banaaaaaanaaas';

console.log(
  createVowelSequenceRegex("bananas"),
  createVowelSequenceRegex("bananas").test(sampleText)
);


function isInvalid(text) {
  return (
    blacklist.some(word =>
      createVowelSequenceRegex(word).test(text)
    )
  );
}
const blacklist = ["sandwhich", "banana", "cheese"];

console.log(
  'isInvalid("I love bananas") ?',
  isInvalid("I love bananas")
);
console.log(
  'isInvalid("I love banaaaaaanaaas") ?',
  isInvalid("I love banaaaaaanaaas")
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Upvotes: 1

Daniel Cheung
Daniel Cheung

Reputation: 4819

If you want a regex that is this /b+a+n+a+n+a+s+/, you can probably achieve this by creating this pattern.

const word = 'bananas'
// add a `+` after each character in the string
const pattern = word.split('').map(char => char + '+').join('') // "b+a+n+a+n+a+s+"

The + means the character before is repeated with occurrence >= 1

new RegExp(pattern, 'i').test('banaaaaaanaaas') // true

However, if you only want vowels to repeat, you'll just need to check if the character is one of the vowels.

const vowels = ['a', 'e', 'i', 'o', 'u']
const word = 'bananas'
// add a `+` after each vowel in the string
const pattern = word
  .split('')
  .map(char => vowels.indexOf(char) > -1 ? char + '+' : char)
  .join('') // "ba+na+na+s"

Upvotes: 2

Related Questions