Email validation in Actionscript 3
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)
|
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'@' 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 |
/* https://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("");
*
* // if you'd rather validate an catch an error you can use:
* EmailValidator.validate("");
*
* // You can also specify which class you;d rather throw an error in case the email isn't valid:
* EmailValidator.validate("bad@", MyErrorClass);
*
* // You can also specify the message to be passed to the error class
* EmailValidator.validate("bad@", 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(", ");
*
* // If you specify an arbitrary separator to test. This will return true:
* EmailValidator.isValidEmailList("; ", ";");
* // But using the default (",") separator, this will return false:
* EmailValidator.isValidEmailList("; ",);
*/
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.
* email The email address as a String
* 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
Thanks very much but... why that execute the method and don't send a boolean ?: trace(EmailValidator.isValidEmail(""));
I would affect the error message to a textfield and display it in (without create a class just for it) but your fonction only return intern chek ... for example :
if (EmailValidator.isValidEmail(textFieldEmail.text)==false){ textFieldError = "my message"; }
don't work :/ thanks
Wow, This is the best pattern I've met on the web. Lukegill, the pattern is important. This works also great:
function isValidEmail(email:String):Boolean { var emailExpression:RegExp = /^[A-Z0-9._%+-]+@(?:[A-Z0-9-]+.)+[A-Z]{2,4}$/i; // this is the pattern here return emailExpression.test(email); }
Now lukegill, your pattern accepts nonsense like . The pattern here only accepts dots seperated with valid characters instead:
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?
I have tested the pattern and found a bug. It allows the more then 4 letters for top level domain.
I have found another /^[A-Z0-9._%+-]+@(?:[A-Z0-9-]+.)+[A-Z]{2,6}$/i
The difference is the slash before dot. This pattern also allows .museum top level domain. Source is http://www.regular-expressions.info/email.html
Best Regards
Have the last word