Search code examples
javascriptregexemail-validation

Email Regex Validation for Name and Surname


I am trying to validate some email addresses.

The email addresses can be in this format:-

1)test@test.com
2)<test@test.com>
3) Name Surmame <test@test.com>
4) Name, Surname <test@test.com>
5) Name(multiple) Surname(multiple) <test@test.com>
6) Name(multiple), Surname(multiple) <test@test.com>

So far I have managed to validate the first 4 scenarios, however I am stuck to validate the last scenario.

I have constructed 4 Regexes so far, each to test the scenario.

So I have the following regexes for the scenarios

1) /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
2) /^<[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?>)*$/
3) /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+[\n# $&:\n\t]+[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+[\n# $&:\n\t]+<[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?>)*$/
4) /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+[\n# $&:\n\t]+[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+[\n# $&:\n\t]+<[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?>)*$/

Is it possible to manipulate the last regex (4) so that it can also validate multiple names and surname?

Thanks for your help and time


Solution

  • This regex will do it (including diacritics):

    /^(([().!#$%&'*+\/=?^_`{|}~\u00BF-\u1FFF\u2C00-\uD7FF\w-]+[,\n#\s$&:\n\t]+){2,}){0,}(?:<){0,1}[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9]))(?:>){0,1}$/igm
    

    The following line checks for names, including diacritics \u00BF-\u1FFF\u2C00-\uD7FF\w- (not the e-mail). It is wrapped in a capturing group which evaluates the if there are any names. If there are names A second capturing group within checks if there are at least two {2,}. It's a compressed version since we don't need to discriminate between a first and last name.

    The <> are enclosed in non-capturing groups and should occur zero or one time.

    /(([().!#$%&'*+\/=?^_`{|}~\u00BF-\u1FFF\u2C00-\uD7FF\w-]+[,\n#\s$&:\n\t]+){2,}){0,}/
    

    const regEx = /^(([().!#$%&'*+\/=?^_`{|}~\u00BF-\u1FFF\u2C00-\uD7FF\w-]+[,\n#\s$&:\n\t]+){2,}){0,}(?:<){0,1}[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9]))(?:>){0,1}$/ig;
    const emails = document.querySelectorAll("div");
    
    emails.forEach(element => {
      if (element.textContent.match(regEx))
      {
        element.classList.add("match");
      }
    });
    div.match {
      color: #ff0000;
    }
    <div>test@test.com</div>
    <div><test@test.com></div>
    <div>Näme Surmame &lt;test@test.com&gt;</div>
    <div>Name, Surname &lt;test@test.com&gt;</div>
    <div>Name 北京市 Surname surname2 Surname3 &lt;test@test.com&gt;</div>
    <div>Name (name 2), Surname-surname2 &lt;test@test.com&gt;</div>
    <div>Name &lt;test@test.com&gt;</div>
    <div>test @test.com</div>
    <div>isthis3avalid test &lt;test@test&gt;</div>
    </textarea>