9

I'm trying to construct an email form that takes multiple comma separated emails as an input and verifies them using HTML5. I want to use the following regex to sanity check the input:

\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b

Here's what I've tried

This doesn't seem to work for more than one:

<input type="email" pattern="\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b" value="" multiple>

This works, but only does the built in email validation, which seems to be something like .+@.+.

<input type="email" value="" multiple>

Is there a way to mix pattern and multiple so the regex checks each item in the comma separated list?

I have a demo here: http://codepen.io/ben336/pen/ihjKA

Ben McCormick
  • 25,260
  • 12
  • 52
  • 71

3 Answers3

14

Try this:

<input type="email" multiple pattern="^([\w+-.%]+@[\w-.]+\.[A-Za-z]{2,4},*[\W]*)+$" value="">

Update:

Using <input type="email" value="" multiple> does seem to be bugged by letting "a@b" pass. Though I would go with this method to keep the semantics as you said, and simply use validation on the server side as well just in case someone tries to submit an email like "a@b".

Just as a note, you should always validate on the server side for security reasons anyway, as client side validation can be bypassed very easily.

Ryan
  • 3,726
  • 3
  • 26
  • 38
  • mmhmm, that seems to match the specific syntax of the comma delimited emails, but it lacks the built in semantic/practical advantages of using the html5 email and multiple fields. This is just a plain input with a single value, and if it fails to match it doesn't tell the user what its looking for. If I can't get the built in validation to work, I'll be looking to do it in JS instead so I can give specific helpful messages. – Ben McCormick Oct 07 '13 at 17:52
  • FWIW this also allows empty entries (IE `a@test.com,,,b@test.com,`) which I suppose you could view as a feature or a bug, but its not something I want. – Ben McCormick Oct 07 '13 at 17:55
  • However, after looking at it further, it looks like I can combine this with the email and multiple attributes to get the effect I want. Upvote. – Ben McCormick Oct 07 '13 at 17:59
  • If you revise your answer to show that this can be combined with email and multiple to maintain the advantages of the html5 attributes, I will accept. – Ben McCormick Oct 07 '13 at 18:03
  • Why do you assume `a@b` would be an invalid email? – robertc Oct 07 '13 at 18:14
  • @robertc because there are specifications for what is a valid email. The detailed tech spec is here: http://tools.ietf.org/html/rfc5322#section-3.4, and there's a more human friendly description on wikipedia: http://en.wikipedia.org/wiki/Email_address#Valid_email_addresses. Essentially, the domain part of an email can be a valid hostname, or a valid IP address. "b" is neither of those. – Ben McCormick Oct 07 '13 at 18:24
  • It seems local domains (such as "b" in this case) are valid, my bad. Looks like different validators disagree on this. Such as PHP's filter_var implementation, which says "a@b" is invalid. – Ryan Oct 07 '13 at 18:28
  • 1
    @ben336 Yes, there are. `b` is a valid hostname, that's why HTML5 allows it. Other valid email addresses would be `root@localhost` and `me@mymachine`. There are perfectly good reasons why you might want to avoid accepting email addresses like these on a web form exposed to the general internet, but the format is not one of them. – robertc Oct 07 '13 at 18:38
  • Note that [the spec for HTML5's interpretation of what constitutes a validly formatted email address is here](http://www.w3.org/TR/html5/forms.html#valid-e-mail-address). – robertc Oct 07 '13 at 18:47
  • 1
    @robertc fair enough. Did some more research and learned a bit more about it. Thanks for setting me straight :) – Ben McCormick Oct 07 '13 at 18:53
  • 1
    `[\w-.]` should be changed to `[\w\-.]` escaping the `-` which is otherwise treated as a range within square brackets. – ChrisWren Aug 31 '15 at 17:27
4

Is there a way to mix pattern and multiple so the regex checks each item in the comma separated list?

Yes. If the regex to match an element is foo, then

^(?:foo(?:,(?!$)|$))*$

will match a comma separated list of foos.

The separator is (?:,(?!$)|$) which will match either a required comma that does not end the input, or the end of input.

That separator is horribly ugly, but allows you to avoid duplicating the "foo" as long as no suffix of the separator is a required non-empty prefix of the body.

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
0

You could read the input in with javascript and split the input on commas.

function() {
var inputString = document.getElementById('emailinput').value;
var splitInput = inputString.split(',');

var pattern = /"your regex pattern"/;

var match = true;

for(i=0;i<splitInput.length;i++) {
  if(!splitInput.match(pattern)){
    match = false;
  }
}

return match;
}
Justin
  • 471
  • 4
  • 16
  • hi Justin, I'm looking for a native HTML solution here. I'm aware that its trivial to do this with JS. – Ben McCormick Oct 07 '13 at 18:07
  • If you tag your question with javascript, you are going to get javascript responses. – Justin Oct 07 '13 at 18:11
  • 1
    I tagged it with JS because html5 regexes use the javascript regex language. I was pretty specific about what I was looking for I think. If you look at the history/updates to the question you'll see I actually added the js tag after the fact, with that caveat. I haven't downvoted you or anything, but your answer isn't addressing the specific question I asked, how to combine the pattern, multiple, and email attributes to validate a list of emails with html5 – Ben McCormick Oct 07 '13 at 18:19