Email validation in Actionscript 3

Email is surprisingly hard to validate. Looking at how flex does it, one wonders if it couldn't be easier (and better).

I've been playing with flex lately and I though the best way to get the hang of it was to use it in small pieces. One of the most obvious places for using the flex framework seemed form validation. Since it is enterprise ready, validation must be top notch. And then I stumbled upon the monstrous 500+ lines of code mx.validators.EmailValidator class. Sure, it's doing a lot more than checking if a String is a valid email address. It will tell you if there is too litle at signs, too many at signs, and many other possible combination of invalid email addresses.

Wow! This is such a case of over engineering! If someone is typing a email addresses on a form, they probably know what it looks like. I've never seen such detailed error messages, and honestly, that's a good thing. Using the EmailValidator from flex will weight 6kb of sources. If it's that complex it sure will do a great job at validating emails, you'd think. But shockingly, the email validation is a great hack: no regex just a bunch of string searches such as:

1
2
var ampPos:int = emailStr.indexOf("@");
if (ampPos == -1)
And so forth. Ouch! Regexes can be daunting and intimidating, but sometimes avoiding a regex will cause a lot more trouble that it will save you. This is an invalid email address, according to the flex validator: "arthur+latenight@somedomain.com". Not only plus signs are legal at the address part, but they're very useful. If your mail server is configured correctly (and unfortunately many aren't) and you have an email account such as "arthur@somedomain.com", then you can use many variations of "arthur+a.web.store@somedomain.com" and still get those delivered to you. This is great for checking if a company has passed your personal information to others, or generating automated rules for filtering or forwarding. Gmail allows that, and I use it all the time.

Getting email validation right is tough. Zeh couldn't get his email to be accepted in so many places he had to change it. The spec allows many variations such as: arthur'@'debert@somedomain.com and other bizarre cases. You don't have to allow them all, but you should definitely allow for the most common ones. Flex, being a framework for client side programming, should really do a better job at validating emails.

In the end you have a heavy, tightly coupled framework that deals with really edge cases (such as warning a user that his email has too many at signs!) but not taking enough care to validate emails correctly.

I've hacked an EmailValidator class that is much more light weight and hopefully gets most emails right. You can download it here. Sample usage below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/* http://www.stimuli.com.br/, Arthur Debert
*/
package br.com.stimuli.mona.validators{
    /*// usage
    * import br.com.stimuli.mona.validators.EmailValidator;
    * 
    * // will return a boolean
    * EmailValidator.isValidEmail("someone@someplace.com");
    * 
    * // if you'd rather validate an catch an error you can use:
    * EmailValidator.validate("someone@someplace.com");
    * 
    * // You can also specify which class you;d rather throw an error in case the email isn't valid:
    * EmailValidator.validate("bad@email@someplace.com", MyErrorClass);
    * 
    * // You can also specify the message to be passed to the error class
    * EmailValidator.validate("bad@email@someplace.com", Error, "Bad email!");
    * 
    * // If you have an input where people can type a few email addresses you can validate a whole list
    * // This will separate and trim each word of text:
    * EmailValidator.isValidEmailList("someone@someplace.com, afriend@otherplace.com");
    * 
    * // If you specify an arbitrary separator to test. This will return true:
    * EmailValidator.isValidEmailList("someone@someplace.com; afriend@otherplace.com ", ";");
    * // But using the default (",") separator, this will return false:
    * EmailValidator.isValidEmailList("someone@someplace.com; afriend@otherplace.com ",);
    */
    public class EmailValidator{

        public function EmailValidator() {
            throw new Error("The EmailValidator class is not intended to be instantiated.");
        }
        
        // permissive, will allow quite a few non matching email addresses
        public static const EMAIL_REGEX : RegExp = /^[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$/i;

        /** Checks if the given string is a valid email address.
        *  @param email The email address as a String
        *  @return True if the given string is a valid email address, false otherwise.
        */
        public static function isValidEmail(email : String) : Boolean{
            return Boolean(email.match(EMAIL_REGEX));
        }
        
        /* Splits a string with the separator character, strips white characters and checks if all of them are valid
        */
        public static function isValidEmailList(emailList : String, separator : String = ",") : Boolean{
            var addresses : Array = emailList.split(separator);
            for each (var email : String in addresses){
                if (!isValidEmail(email.replace(/\s/, "")))return false;
            }
            return true;
        }
        
        public static function validate(email : String, errorClass : Class = null, errorMessage : String = "Invalid e-mail address.") : void{
            if (isValidEmail(email) )return;
            errorClass = errorClass || Error;
            throw new errorClass(errorMessage)
        }
    }
}

If you catch valid emails that this regex is complaining about, please let me know. you can also get the full scoop on the nitty gritty of email validation here.

getting a third opinion

1.
Marian M.Bida says at

Just run itno this problem, this is my first day in as3 world, thank you.

3.
Chris Ellem says at

Great AS3 example of how to loop over a string...very useful piece of code...great work Arthur...and thanks for sharing.

4.
noponies says at

Nice work.

7.
Felipe Ziliotti says at

Greaaaatttt job!

Tk's for shareeee Arthur!!

:)

8.
Michael Parisi says at

Awesome. Thankz

9.
uday_sgh@yahoo.com says at

That's greate, Email validation is a small task, but here they are using so many lines of code.

Thanks, Uday

11.
Timo Virtanen says at

Thanks. Works like a charm :)

15.
lukegill says at

I've blogged about a much easier way to validate emails in AS3. Including source .fla

Check it out : http://www.lukegill.com/blog/as3-email-validation/

16.
Dan says at

great body of work you have here Arthur!

I notice that your email validator rejects emails with 's in them. e.g. jack.o'shea@gmail.com. Since there are many Irish surnames (and in other langs I presume) written like that, I would think that would be valid?

18.
Dan says at

Hi, back again. How about accented characteds, cedila and other "funny" european chars? I don't know what's really valid though. Here's a little string of the ones that I think cover Spanish, Catalan, French, Italian and probably some others. ·áéíóúñàèìòùñçüïÁÉÍÓÚÀÈÌÙÒÑÇÜÏ Perhaps it'd be better to write the regexp so it excludes unwanted chars rather than only include permitted ones?

19.
Arthur Debert says at

Hi Dan.

Yeah, you do bring good points. I am not sure though, on most server configuration for non-ascii chars in the local domain part, but I suspect it's still pretty uncommon.

Will think this more throughly, though.

Best regards

22.
Adrian Parr says at

@Chrome: When I run your code I get the following in the output window ...

false false

Rather than ...

true false

posted by
Arthur Debert

on

Tagged with:

25 comments so far.
Say something

Other months availabe in 2007

The complete blog archive

The latest entries

Subscribe to comments on this entry: rss feed

Cloud me:
  • Saurabh in Loading Reloaded on

    Brilliant brilliant class. Takes the preloader pain away. Thanks Arthur.

    For anyone else struggling with the infamous null Object errors when loading swfs via Bulkloader, here's something basic you could ...

  • Fernando in Loading Reloaded on

    Hi, Arthur!

    I just want to let you know that I added Bulk Loader to my site called AS3GameGears (http://www.as3gamegears.com/).

    I am using it on one of our projects. ...

  • Nitin Sharma in Loading Reloaded on

    Hi Junio Vitorino, I am facing the same problem. Can you please tell me, how did you solve this.

    1046: Type was not found or was not a compile-time constant: ...

  • slopps in AS3 Sad bits #1: Deep copying or cloning on

    Wow...good info. I cannot fathom how this was left out of AS3...so frustrating.

    To be clear, if a custom class extends MovieClip (or any DisplayObject) and you attempt to clone ...

  • Elmar Nieser in Maxhaus on

    Thanks for all the information!

    I wanted to show my Isometric Engine wich works pretty ok now thanks to all this info :)

    www.uber.nl <-- its just the engine so ...

Feeds: Entries rss feed Linksrss feed Worksrss feed

A Django joint. hosted on Slicehost