Search code examples
javascriptregexemail-validation

Validate Email with regular expression where the number of extensions in the domain part can vary


I need a regular expression to match a pattern like this. I have tried using this -

if(str.match(/^([a-zA-Z-\.]+)@([a-zA-Z]{1,5})\.([a-zA-Z]{1,5})(\.[a-zA-Z]{1,5})?(\.[a-zA-Z]{2,3})?$/)){
  console.log("the email is valid");
}

But this counts user@aaa.bb.cccc as valid whereas it should not be.

The full requirements of the email to be valid -

  1. The username part of the email can have only words(case insensitive), dots(.) and dashes(-). Length of 1 or more characters.

  2. The domain name part can have 2 to 4 extensions. For example, username@ext.ext.ext.ext this email has 4 extensions.

  3. All the extensions can only have words(case insensitive), and the length can of 1 to 5 characters long except the last extension. The last extension can only be of 2 to 3 characters long. For Example,

    user@aaa.bb.cccc.dd is valid

    user@aaa.bv.cccc is not valid

    I am having trouble with solving this part. As the extension count can vary I don't know How to check if only the last part of the email has 2 to 3 characters?

I know this type of question might be answered before. I am new to Regular Expressions and I could not find a solution to my problem.


Solution

  • You could match a single [a-zA-Z]{1,5} after the @.

    Then match 0 to 2 times \.[a-zA-Z]{1,5} and match \.[a-zA-Z]{2,3} at the end to match 2-4 parts in total.

    ^[a-zA-Z.-]+@[a-zA-Z]{1,5}(?:\.[a-zA-Z]{1,5}){0,2}\.[a-zA-Z]{2,3}$
    

    Regex demo

    If you want to match "words", you might also use \w instead of using [a-zA-Z] to also match digits and _

    const pattern = /^[a-zA-Z.-]+@[a-zA-Z]{1,5}(?:\.[a-zA-Z]{1,5}){1,2}\.[a-zA-Z]{2,3}$/;
    [
      "user@aaa.bb.cccc.dd",
      "user@aaa.bb.cccc.dd.ee",
      "user@aaa.bv.cccc"
    ].forEach(s => {
      console.log(`the email is ${pattern.test(s) ? "" : "not "}valid for ${s}`)
    });