17

i am looking for a regular express to validate a list of email addresses like the following

test1@abd.com;test.test@abc.com;test3@test.com

and

test1@abd.com;test.test@abc.com;test3@test.com;

optional ";" at the end of the list.

thanks,

Eatdoku
  • 5,949
  • 13
  • 57
  • 93

6 Answers6

21

From: http://regexlib.com/RETester.aspx?regexp_id=1007

^(([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}){1,25})+([;.](([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}){1,25})+)*$
Alan Moore
  • 68,531
  • 11
  • 88
  • 149
Evan Mulawski
  • 51,888
  • 11
  • 110
  • 142
  • I dropped this one into Expresso and it complained that it couldnt parse it – rtpHarry Dec 04 '10 at 01:31
  • At first glance, this will allow any number of email addresses, without any separators, followed by any number of semicolons each followed by at least one character. So this would be valid: "example@domain.comexample2@domain.com;$;8;asdf" – eyelidlessness Dec 04 '10 at 01:38
  • 1
    The entire expression did not post properly. The correct expression is on the site li ked in the post. – Evan Mulawski Dec 04 '10 at 02:46
  • @Evan: it didn't post properly because you used `` tags instead of SO's own formatting capabilities. You should try to use the SO version whenever you can; it's quite good. – Alan Moore Dec 04 '10 at 08:04
  • @Alan: Because I posted with an iPad, I did not have access to the formatting tools. – Evan Mulawski Dec 04 '10 at 14:25
  • 1
    Evan: Does iPad not let you insert four spaces at the beginning of a line? I see now that iPad is backtick-challenged, but all other SO markup can be typed in manually. And there seem to be some workarounds for the backtick thing: http://meta.stackoverflow.com/search?q=iPad – Alan Moore Dec 04 '10 at 19:17
  • what happen i would like to allow an optional ";" at the end of the email list? – Eatdoku Dec 06 '10 at 22:11
  • add [;]{0,1} at the end before $ to allow optional ";" at the end of the email list. – Eatdoku Dec 06 '10 at 23:06
  • That certainly does not look RFC compliant to me. – tchrist Feb 01 '11 at 00:38
  • -1 .... this produces a mess when I test it against a@b.com at: http://www.regular-expressions.info/javascriptexample.html – dsdsdsdsd Nov 13 '13 at 08:52
  • 2
    i found this issue At first glance, this will allow any number of email addresses, without any separators, followed by any number of semicolons each followed by at least one character. So this would be valid: "example@domain.comexample2@domain.com;$;8;asdf" .how to fix this.any help – Coder Jan 27 '17 at 04:51
  • @NikhilVC: You may want to just split the string on a separator of your choice and validate each address individually. – Evan Mulawski Jan 27 '17 at 14:58
  • 1
    @Evan Mulawski:then why would use this regex – Coder Feb 02 '17 at 13:12
  • @NikhilVC - True, I just found this error as well. To fix this, I removed the 3rd `+` sign (and the parens `()` around the first mega group), then I changed `[;.]` to a plain `;` - I actually changed that part to `;[ ]{0,1}` in case the user puts a space after the semi-colon, but this isn't necessary – Blundering Philosopher Feb 18 '18 at 12:05
  • @NikhilVC - I added this as [**an answer**](https://stackoverflow.com/questions/4351349/regular-expression-for-delimited-email-address/48851660#48851660) below - Hopefully it works for you. – Blundering Philosopher Feb 18 '18 at 12:28
7

“You call that a knife???” —Crocodile Dundee

Actually, all those are very poor patterns for matching a mail address. To strictly validate an RFC 5322 mail address with zero false negatives and zero false positives, you need this precise pattern:

  (?x)

  (?(DEFINE)

     (?<address>         (?&mailbox) | (?&group))
     (?<mailbox>         (?&name_addr) | (?&addr_spec))
     (?<name_addr>       (?&display_name)? (?&angle_addr))
     (?<angle_addr>      (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
     (?<group>           (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ; (?&CFWS)?)
     (?<display_name>    (?&phrase))
     (?<mailbox_list>    (?&mailbox) (?: , (?&mailbox))*)

     (?<addr_spec>       (?&local_part) \@ (?&domain))
     (?<local_part>      (?&dot_atom) | (?&quoted_string))
     (?<domain>          (?&dot_atom) | (?&domain_literal))
     (?<domain_literal>  (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
                                   \] (?&CFWS)?)
     (?<dcontent>        (?&dtext) | (?&quoted_pair))
     (?<dtext>           (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])

     (?<atext>           (?&ALPHA) | (?&DIGIT) | [!#\$%&'*+-/=?^_`{|}~])
     (?<atom>            (?&CFWS)? (?&atext)+ (?&CFWS)?)
     (?<dot_atom>        (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
     (?<dot_atom_text>   (?&atext)+ (?: \. (?&atext)+)*)

     (?<text>            [\x01-\x09\x0b\x0c\x0e-\x7f])
     (?<quoted_pair>     \\ (?&text))

     (?<qtext>           (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
     (?<qcontent>        (?&qtext) | (?&quoted_pair))
     (?<quoted_string>   (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
                          (?&FWS)? (?&DQUOTE) (?&CFWS)?)

     (?<word>            (?&atom) | (?&quoted_string))
     (?<phrase>          (?&word)+)

     # Folding white space
     (?<FWS>             (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
     (?<ctext>           (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
     (?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment))
     (?<comment>         \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
     (?<CFWS>            (?: (?&FWS)? (?&comment))*
                         (?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

     # No whitespace control
     (?<NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])

     (?<ALPHA>           [A-Za-z])
     (?<DIGIT>           [0-9])
     (?<CRLF>            \x0d \x0a)
     (?<DQUOTE>          ")
     (?<WSP>             [\x20\x09])
   )

   (?&address)  # finally, match a mail address

I discuss this in more detail in this answer.

That needs a Perl Compatible Regular Expression (PCRE) library, or Perl itself, to work properly. I cannot guarantee that perl incompatible pattern engines will correctly handle the recursion.

Community
  • 1
  • 1
tchrist
  • 74,913
  • 28
  • 118
  • 169
4

@Evan's answer is close, but the expression matches these scenarios which are invalid:

  1. a@test.comb@test.comc@test.com (no delimiters)
  2. a@test.com;b@test.com.c@test.com (period . accepted as delimiter)
  3. a@test.com;b@test.comc@test.com (only 1st delimiter matched - extension of problem #1)

To fix these (and simplify a little bit), I made these changes:

  1. Removed the 3rd + sign, and the outer parens () surrounding the first email address.
  2. Change [;.] to a plain ; delimiter - I actually changed that part to ;[ ]{0,1} because I wanted the expression to match spaces after the semi-colon delimiter.
  3. Similar to #1, remove the final + sign in the expression, and the outer parens () between the delimiter (step #2) and the final closing paren with the star after it - )*

Here is the final expression (allowing an optional space after the ; delimiter:

/^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}){1,25}(;[ ]{0,1}([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}){1,25})*$/
Blundering Philosopher
  • 5,116
  • 2
  • 35
  • 50
2

I use this:

^(([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}){1,25}(($)|( *;+ *$)|( *;+ *(?=[a-zA-Z0-9_\-\.]))))*$

https://regexr.com/3gth7

alexander.polomodov
  • 4,849
  • 14
  • 35
  • 42
Jck
  • 21
  • 3
  • This one actually allows for the optional semicolon at the end, as requested in the initial question. Upvote! – Joe Coyle Sep 24 '19 at 12:39
1

I needed to allow for the presence of white space around the delimiter, so I used this modification of Evan Mulawski's answer:

^(([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}){1,25})+(\s*[;.]\s*(([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}){1,25})+)*$

Test it at: http://regexlib.com/RETester.aspx?regexp_id=13126

Tim S
  • 2,212
  • 14
  • 22
-1

here is another ^(0-9a-zA-Z@([0-9a-zA-Z][-\w][0-9a-zA-Z].)+[a-zA-Z]{2,9})$