18

Trying to validate a comma-separated email list in the textbox with asp:RegularExpressionValidator, see below:

<asp:RegularExpressionValidator ID="RegularExpressionValidator1"
                    runat="server" ErrorMessage="Wrong email format (separate multiple email by comma [,])" ControlToValidate="txtEscalationEmail"
                    Display="Dynamic" ValidationExpression="([\w+-.%]+@[\w-.]+\.[A-Za-z]{2,4},?)" ValidationGroup="vgEscalation"></asp:RegularExpressionValidator>

It works just fine when I test it at http://regexhero.net/tester/, but it doesn't work on my page.

Here's my sample input:

[email protected],[email protected]

I've tried a suggestion in this post, but couldn't get it to work.

p.s. I don't want a discussion on proper email validation

Community
  • 1
  • 1
roman m
  • 26,012
  • 31
  • 101
  • 133
  • Could you show the code which adds the regex to the validator? – Mikael Svenson Dec 10 '10 at 19:55
  • Regex Hero returns two matches with your original regular expression. Donut's solution gives just one match (as it should). I suppose that means that the RegularExpressionValidator has some unique matching behavior in terms of what justifies a match. Maybe two side-by-side matches doesn't justify a match. It shouldn't be hard to figure that out. – Steve Wortham Dec 10 '10 at 20:39
  • These ad-hoc regexes are basically all wrong. Please review https://stackoverflow.com/questions/201323/how-can-i-validate-an-email-address-using-a-regular-expression/201378#201378 – tripleee Feb 09 '23 at 08:29

16 Answers16

32

This Regex will allow emails with spaces after the commas.

^[\W]*([\w+\-.%]+@[\w\-.]+\.[A-Za-z]{2,4}[\W]*,{1}[\W]*)*([\w+\-.%]+@[\w\-.]+\.[A-Za-z]{2,4})[\W]*$

Playing around with this, a colleague came up with this RegEx that's more accurate. The above answer seems to let through an email address list where the first element is not an email address. Here's the update which also allows spaces after the commas.

Matt
  • 5,573
  • 4
  • 33
  • 37
17

Try this:

^([\w+-.%]+@[\w-.]+\.[A-Za-z]{2,4},?)+$

Adding the + after the parentheses means that the preceding group can be present 1 or more times.

Adding the ^ and $ means that anything between the start of the string and the start of the match (or the end of the match and the end of the string) causes the validation to fail.

Donut
  • 110,061
  • 20
  • 134
  • 146
14

The first answer which is selected as best matches the string like [email protected]@abc.com which is invalid.

The following regex will work for comma separated email ids awesomely.

^([\w+-.%]+@[\w.-]+\.[A-Za-z]{2,4})(,[\w+-.%]+@[\w.-]+\.[A-Za-z]{2,4})*$

It will match single emailId, comma separated emailId but not if comma is missed.

First group will match string of single emailId. Second group is optionally required by '*' token i.e. either 0 or more number of such group but ',' is required to be at the beginning of such emailId which makes comma separated emailId to match to the above regex.

Laxmi Prasad
  • 442
  • 5
  • 15
3

A simple modification of @Donut's answer allows adjacent commas, all TLDs of two characters or more, and arbitrary whitespace between email addresses and commas.

^([\w+-.%]+@[\w-.]+\.[A-Za-z]{2,}(\s*,?\s*)*)+$

You will need to split and remove whitespace and empty strings on your side, but this should be an overall better user experience.

Examples of matched lists:

dunxen
  • 73
  • 2
  • 7
1
^([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+,*[\W]*)+$

This will also work. It's a little bit stricter on emails, and doesn't that there be more than one email address entered or that a comma be present at all.

Stan
  • 1,191
  • 2
  • 15
  • 27
1

The solution that work for me is the following

^([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)(,([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+))*
Jorge Santos Neill
  • 1,635
  • 13
  • 6
1

The following RegEx will work even with some of the weirdest emails out there, and it supports a comma between emails.

((?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]),?)+

A few Examples:

Valid: [email protected]
Valid: [email protected]
Valid: [email protected],[email protected]
Valid: [email protected],/#!$%&'*+-/=?^_`{}|[email protected],"!#$%&'-/=^_`{}|~.a"@solar.org
Invalid: planet [email protected]

Hope This helps.

vinay
  • 21
  • 4
1
^([\w+.%-]+@[\w.-]+\.[A-Za-z]{2,})( *,+ *(?1))*( *,* *)$

The point about requiring a comma between groups, but not necessarily at the end is handled here - I'm mostly adding this as it includes a nice subgroup with the (?1) so you only define the actual email address regex once, and then can muck about with delimiters.

Email address ref here: https://www.regular-expressions.info/email.html

  • Unfortunately, recursive pattern doesn't work with all regex flavor, not sure for .net – Toto Jan 30 '20 at 14:36
1

This works for me in JS and TS

^([a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*)(([, ]+[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])\.([a-z0-9]([a-z0-9-]*[a-z0-9]))*)?)*$

You can check it out here https://regex101.com/r/h0l9ks/1

Oded BD
  • 2,788
  • 27
  • 30
0

The regex below is less restrictive and more appropriate for validating a manually-entered list of comma-separated email addresses. It allows for adjacent commas.

^([\w+-.%]+@[\w-.]+\.[A-Za-z]{2,4},*[\W]*)+$
Rieekan
  • 56
  • 8
0

Use the following regex, it will resolve your problem. The following regex will entertain post and pre spaces with comma too

/^((([a-zA-Z0-9_-.]+)@([a-zA-Z0-9_-.]+).([a-zA-Z\s?]{2,5}){1,25})(\s?,\s*?))$/
Chuck Norris
  • 15,207
  • 15
  • 92
  • 123
Hisham Javed
  • 159
  • 2
  • 4
0

I'm a bit late to the party, I know, but I figured I'd add my two cents, since the accepted answer has the problem of matching email addresses next to each other without a comma.

My proposed regex is this:

^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}(,[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})*$

It's similar to the accepted answer, but solves the problem I was talking about. The solution I came up with was instead of searching for "an email address followed by an optional comma" one or more times, which is what the accepted answer does, this regex searches for "an email address followed by an optional comma prefixed email address any number of times".

That solves the problem by grouping the comma with the email address after it, and making the entire group optional, instead of just the comma.

Notes: This regex is meant to be used with the insensitive flag enabled.
You can use whichever regex to match an email address you please, I just used the one that I was already using. You would just replace each [A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,} with whichever regex you want to use.

0

The easiest solution would be as following. This will match the string with comma-separated list. Use the following regex in your code.

Regex: '[^,]+,?'

Deep
  • 342
  • 3
  • 12
0
^([\w+-.%]+@[\w-.]+\.[A-Za-z]+)(, ?[\w+-.%]+@[\w-.]+\.[A-Za-z]+)*$

Works correctly with 0 or 1 spaces after each comma and also for long domain extensions

Dharman
  • 30,962
  • 25
  • 85
  • 135
manu4rhyme
  • 83
  • 1
  • 4
0

The regex i have for this issue all well except that we need to add comma after every email address.

^((\s*?)[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z,]{2,4}(\s*?),)*

The explanation for this will be like this:

  1. (\s*?) will allow spaces at the start.
  2. [a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z,]{2,4} is common email pattern.
  3. (\s*?) will allow space at the end too.
  4. , will restrict comma.
0

For me, this one works perfectly for multiple emails:

^(\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]{2,4}\s*?,?\s*?)+$
RegEx Component Explanation
^ Matches the start of the string.
\w+ Matches one or more word characters (letters, digits or underscores).
((-\w+)|(\.\w+))* Matches zero or more occurrences of a hyphen followed by one or more word characters or a period followed by one or more word characters.
\@ Matches the @ symbol.
[A-Za-z0-9]+ Matches one or more letters or digits.
((\.|-)[A-Za-z0-9]+)* Matches zero or more occurrences of a period or hyphen followed by one or more letters or digits.
\.[A-Za-z0-9]{2,4} Matches a period followed by two to four letters or digits.
\s*?,?\s*? Matches optional whitespace followed by an optional comma followed by optional whitespace.
+ Matches one or more occurrences of the entire expression.
$ Matches the end of the string.
Andreas Violaris
  • 2,465
  • 5
  • 13
  • 26
Laraknown
  • 1
  • 2
  • 2
    While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Yunnosch Feb 09 '23 at 08:10
  • 1
    "Perfect" seems like a stretch. It will not work with plussed addresses, for one thing. The restriction on top-level fomains to ones with 2 to 4 characters is also an obvious flaw; it will fail for `.museum`, `.space`, etc. as well as [IDNA](https://en.wikipedia.org/wiki/Internationalized_domain_name) ones like `.рф` (the subdomain regex is also wrong for IDNA). – tripleee Feb 09 '23 at 08:27