Reputation: 3081
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
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
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