Testing UK Postcodes using Javascript

I got very sidetracked today, creating a JavaScript routine to validate UK postcodes. I actually made it into a Dojo package, and will be trying to get it accepted into the main Dojo release, but here is an alternative version which doesn’t need Dojo:

isValidUkPostcode = function(/*String*/value, /*Object?*/flags){
// summary: A regular expression to check for valid UK postcodes
//
// value : the string to be tested
// flags : An object.
// flags.strictChecking: check strictly against conventions
// published in
// http://www.govtalk.gov.uk/gdsc/html/frames/PostCode.htm
// i.e. exclude certain letters from certain positions -
// NB These conventions may change in the future if
// operationally required.
// flags.fullCode: check for full-length postcodes, i.e. incode
// and outcode
// flags.outCodeOnly: check for outcode only postcodes,
// e.g. SW1V

// assign default values to missing paramters
flags = (typeof flags == "object") ? flags : {};
if(typeof flags.strictChecking != "boolean"){ flags.strictChecking = true; }
if(typeof flags.fullCode != "boolean"){ flags.fullCode = true; }
if(typeof flags.outCodeOnly != "boolean"){ flags.outCodeOnly = false; }

var numericPositionRE = "[0-9]";
var alphaPositionRE = "[A-Z]";

// Outcode
if(flags.strictChecking) {
var firstPositionRE = "[A-PR-UWYZ]";
var secondPositionRE = "[A-HK-Y]";
var thirdPositionRE = "[A-HJKS-UW]";
var fourthPositionRE = "[ABEHMNPRV-Y]";
} else {
var firstPositionRE = alphaPositionRE;
var secondPositionRE = alphaPositionRE;
var thirdPositionRE = alphaPositionRE;
var fourthPositionRE = alphaPositionRE;
}

var outCodeRE =
"(" + firstPositionRE + numericPositionRE + ")|("
+ firstPositionRE + numericPositionRE + numericPositionRE + ")|("
+ firstPositionRE + secondPositionRE + numericPositionRE + ")|("
+ firstPositionRE + secondPositionRE + numericPositionRE + numericPositionRE + ")|("
+ firstPositionRE + numericPositionRE + thirdPositionRE + ")|("
+ firstPositionRE + secondPositionRE + numericPositionRE + fourthPositionRE + ")";

// inCode
if(flags.strictChecking) {
var inCodeAlphaRE = "[ABD-HJLNP-UW-Z]";
} else {
var inCodeAlphaRE = "[A-Z]";
}
var inCodeRE = "([0-9]" + inCodeAlphaRE + inCodeAlphaRE + ")";

// exceptions
if (flags.fullCode & flags.outCodeOnly) {
var exceptionsRE = "(GIR 0AA)|(GIR)";
var postcodeRE = "(" + outCodeRE + " " + inCodeRE + ")|(" + outCodeRE + ")|(" + exceptionsRE + ")";
} else if (flags.outCodeOnly) {
var exceptionsRE = "GIR";
var postcodeRE = "(" + outCodeRE + ")|(" + exceptionsRE + ")";
} else {
var exceptionsRE = "GIR 0AA";
var postcodeRE = "(" + outCodeRE + " " + inCodeRE + ")|(" + exceptionsRE + ")";
}

var re = new RegExp("^" + postcodeRE + "$", "i");
return re.test(value); // Boolean
}