skip to Main Content

I want to test if a string ONLY contains specific substrings (as whole words) / spaces

I’ve written some code and it works, but I am concerned it is not very efficient

Is there a more efficient way of doing this?

Here’s my inefficient code

const str1 = 'a♭ apple a a a a a apple   a♭ a' // valid
const str2 = 'a♭ apple a a a a a apple   a♭ aa' // invalid aa
const str3 = 'a♭ apple ad  a a a apple   a♭ a' // invalid ad

const allowedSubstrings = [
  'a', 'a♭', 'apple'
]

const isStringValid = str => {
  allowedSubstrings.forEach(sub => {
    // https://stackoverflow.com/a/6713427/1205871
    // regex for whole words only
    const strRegex = `(?<!\S)${sub}(?!\S)`
    const regex = new RegExp(strRegex, 'g')
    str = str.replace(regex, '')
  })
  str = str.replaceAll(' ', '')
  // console.log(str)
  return str === ''
}

console.log('str1', isStringValid(str1))
console.log('str2', isStringValid(str2))
console.log('str3', isStringValid(str3))

2

Answers


  1. One approach which I can think of(which avoids complex regex) would be to:

    1. split the string based on one or more whitespace characters(space, tabs or others)
    2. check if every word in the words array(created by above split) is included in the allowedSubstrings array.
    const str1 = 'a♭ apple a a a a a apple   a♭ a'; // valid
    const str2 = 'a♭ apple a a a a a apple   a♭ aa'; // invalid aa
    const str3 = 'a♭ apple ad  a a a apple   a♭ a'; // invalid ad
    const str4 = ' a♭ apple a a a a a apple   a♭ a'; // valid
    const str5 = ' a♭ apple a a a a a apple   a♭ a '; // valid
    const str6 = 'a♭ apple a a a a a apple   a♭ a '; // valid
    
    const allowedSubstrings = [
      'a', 'a♭', 'apple'
    ];
    
    const isStringValid = (str) => {
      const words = str.trim().split(/s+/);
      // If the requirement would be to make them valid, we can use trim().
      // const words = str.trim().split(/s+/);
      return words.every(word => allowedSubstrings.includes(word));
    };
    
    // const isStringValid = (str) => str.split(/s+/).every(word => allowedSubstrings.includes(word));
    
    console.log('str1', isStringValid(str1));
    console.log('str2', isStringValid(str2));
    console.log('str3', isStringValid(str3));
    console.log('str4', isStringValid(str4));
    console.log('str5', isStringValid(str5));
    console.log('str6', isStringValid(str6));
    Login or Signup to reply.
  2. A single regular expression pattern that checks whether the string contains only the specified substrings as whole words or spaces. It uses the join('|') method to create an alternation pattern (|) for the allowed substrings and then tests the string against this pattern using test().

    const str1 = 'a♭ apple a a a a a apple   a♭ a'; // valid
    const str2 = 'a♭ apple a a a a a apple   a♭ aa'; // invalid aa
    const str3 = 'a♭ apple ad  a a a apple   a♭ a'; // invalid ad
    
    const allowedSubstrings = [
      'a',
      'a♭',
      'apple'
    ];
    
    const isStringValid = str => {
      const regex = new RegExp(`^((${allowedSubstrings.join('|')})(\s+|$))+$`);
      return regex.test(str);
    };
    
    console.log('str1', isStringValid(str1));
    console.log('str2', isStringValid(str2));
    console.log('str3', isStringValid(str3));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search