Loose email address validation with JavaScript

I was looking for a fairly basic validation routine to weed out intentional garbage from a form email field. All I came across were either too restrictive or didn’t check what could be checked, so I wrote my own (inspired by various scripts on the web).

// pattern to match email addresses loosely
regex1 = /^[^sn@]*[^sn.@]@[^sn.@][^sn@]*(?=.[^s.n @]+$).[^s.n @]+$/;

// pattern to check for double-dots
regex2 = /(?:..)/;

// get the form value and trim whitespace using jQuery
email_address = jQuery.trim($j("#bus_email").val());

if (!email_address.match(regex1) || email_address.match(regex2))
alert("Please check the email address for accuracy!");

The above regex pattern will look for the following points in an email address:

  • Only one @-sign.
  • No spaces in the string.
  • No newlines/linefeeds in the string.
  • One or more characters before the @-sign. The character immediately before @ may not be a period.
  • The character immediately after @ may not be a period.
  • One or more characters after the @-sign, followed by at least one period followed by one or more characters at the end of the string (for the TLD).
  • No two adjacent dots.

The RFC 2822 that defines the email address format is pretty complex, and new TLDs are added from time to time. This script helps to catch typos and randomly entered garbage, but of course has no way to prevent users from entering correctly formed but invalid addresses.

I’m using two separate regular expressions as there doesn’t seem to be a way to negate a string (i.e. two consecutive dots) but only single characters. If someone reading this happens to know how to combine the two regular expressions into one, please let me know!

JavaScript to ID credit card type

I’m working on a subscription page which needs to identify the type of the entered credit card number, and display a logo accordingly. I came up with the following script to ID the card:

// get entered cc_number using jQuery
cc_number = $("#cc_number").val();

// remove spaces and hyphens
cc_number = cc_number.replace(/[ -]/g,"");

// initially the card type is unknown
cardtype = '';
$j("#cc_type").val("");

// define card names and their matching patterns
ccArray = {"visa"  : "^4[0-9]{12}(?:[0-9]{3})?$",
      "mastercard" : "^5[1-5][0-9]{14}$",
      "discover"   : "^6011[0-9]{12}$",
      "amex"       : "^3[47][0-9]{13}$"};

// identify the card type
for (key in ccArray) {
	regex = new RegExp(ccArray[key]);
	if (regex.test(cc_number)) {
		cardtype = key;
		break;
	}
}

I validate the card number next (JS routine available elsewhere on the web), and if that’s ok, display the logo using the card type.