javascriptregexfunctionpangram

Using regular expression to check for pangram in a string error


Roy wanted to increase his typing speed for programming contests. His friend suggested that he type the sentence "The quick brown fox jumps over the lazy dog" repeatedly. This sentence is known as a pangram because it contains every letter of the alphabet.

After typing the sentence several times, Roy became bored with it so he started to look for other pangrams.

Given a sentence, determine whether it is a pangram. Ignore case.

It should return the string pangram if the input string is a pangram. Otherwise, it should return not pangram.

SAMPLE INPUTS

We promptly judged antique ivory buckles for the next prize

// pangram

We promptly judged antique ivory buckles for the prize

// not pangram (missing letter x)

CODE

function pangrams(s) {

   const exp = /[a-z]/gi; 

   if (s.includes(exp)) {
     return 'pangram';
   } else {
     return 'not pangram';
   } 
   
}

TypeError: First argument to String.prototype.includes must not be a regular expression

QUESTION

If I'm solving it correctly otherwise, how can I work around this while still being able to use the regular expression?


Solution

  • Your regular expression is wrong. It will only check if the string contains one letter from a to z. You also aren't testing it properly - String.prototype.includes checks for substrings being included in the larger string, not for regular expression validation.

    If you want to test whether a regular expression matches a string, use .test. To check that all letters exist in a string with a regular expression, you'll have to repeat (?=.*a) for every character, eg:

    const pattern = /^(?=.*a)(?=.*b)(?=.*c)(?=.*d)(?=.*e)...../i;
    return s.test(pattern);
    

    But that's really ugly and repetitive.

    I don't think a regular expression is the way to go here. Consider iterating over character codes to get the characters from A to Z and using .includes instead:

    const test = (str) => {
      const strUpper = str.toUpperCase();
      // start at A
      for (let i = 65; i <= 90; i++) {
        if (!strUpper.includes(String.fromCharCode(i))) {
          return false;
        }
      }
      return true;
    };
    console.log(test('The quick brown fox jumps over the lazy dog'));
    console.log(test('The quick brown fox jumps over the lazy do'));

    If you have to use a regular expression, you can construct it dynamically by iterating over all the character codes:

    const test = (str) => {
      const pattern = new RegExp(
        '^' +
        Array.from(
          { length: 26 },
          (_, i) => `(?=.*${String.fromCharCode(i + 65)})`
        ).join(''),
        'i'
      );
      return pattern.test(str);
    };
    console.log(test('The quick brown fox jumps over the lazy dog'));
    console.log(test('The quick brown fox jumps over the lazy do'));