I have the following regular expression which validates the British National Insurance Number
^([a-zA-Z]){2}( )?([0-9]){2}( )?([0-9]){2}( )?([0-9]){2}( )?([
I think it is better to normalize it first (remove all white-space characters: \s
regex to replace with empty string), then validate.
^[a-zA-Z]{2}[0-9]{6}[a-zA-Z]{1}$
There is a fixed format for National Insurance Number or NINO.
The format of the number is two prefix letters, six digits and one suffix letter.
Neither of the first two letters can be D, F, I, Q, U or V. The second letter also cannot be O. The prefixes BG, GB, NK, KN, TN, NT and ZZ are not allocated.
After the two prefix letters, the six digits are issued sequentially from 00 00 00 to 99 99 99. The last two digits determine the day of the week on which various social security benefits are payable and when unemployed claimants need to attend their Jobcentre to sign on.
The suffix letter is either A, B, C, or D.
The example used is typically AB123456C. Often, the number is printed with spaces to pair off the digits, like this: AB 12 34 56 C.
So, the regex would be,
[A-CEGHJ-PR-TW-Z]{1}[A-CEGHJ-NPR-TW-Z]{1}\s?[0-9]{2}\s?[0-9]{2}\s?[0-9]{2}\s?[A-DFMP ]
[RegularExpression(@"^([ACEHJLMOPRSWXYacehjlmoprswxy][A-CEGHJ-NPR-TW-Za-ceghj-npr-tw-z]|Bb[A-CEHJ-NPR-TW-Za-cehj-npr-tw-z]|Gg[ACEGHJ-NPR-TW-Zaceghj-npr-tw-z]|[KTkt][A-CEGHJ-MPR-TW-Za-ceghj-mpr-tw-z]|Nn[A-CEGHJL-NPR-SW-Za-ceghjl-npr-sw-z]|Zz[A-CEGHJ-NPR-TW-Ya-ceghj-npr-tw-y])[0-9]{6}[A-Da-d ]$", ErrorMessage = "NI Number must be in the correct format.")]
After reading all the answers here I have determined that there isn't a clear answer to this question.
With my regex you will need to strip all spaces out of the string but really you should be doing this anyway for validating most data. This can be achieved easily here are a couple of examples.
PHP
preg_replace('/(\s+)|(-)/', '', $str)
Javascript
str.replace(/ /g,'')
For the validation based off the UK government advice (http://www.hmrc.gov.uk/manuals/nimmanual/nim39110.htm) I constructed the following regex.
/^[A-CEGHJ-PR-TW-Z]{1}[A-CEGHJ-NPR-TW-Z]{1}[0-9]{6}[A-D]{1}$/i
Here is an explanation of this regex
/ # Wraps regex
^ # Beginning of string
[A-CEGHJ-PR-TW-Z]{1} # Match first letter, cannot be D, F, I, Q, U or V
[A-CEGHJ-NPR-TW-Z]{1} # Match second letter, cannot be D, F, I, O, Q, U or V
[0-9]{6} # Six digits
[A-D]{1} # Match last letter can only be A, B, C or D
$ # End of string
/i # Ending wrapper and i denotes can be upper or lower case
Here are some test patterns you can use
Pass
AA 11 22 33 A
BB 44 55 66 B
ZZ 67 89 00 C
Fail
AA 11 22 33 E
DA 11 22 33 A
FA 11 22 33 A
AO 11 22 33 A
As I needed to extend jQuery validate to add this new national insurance number regex I am also including this as it may be useful for someone.
jQuery.validator.addMethod('nino', function(nino, element) {
return this.optional(element) || nino.length >= 9 &&
nino.replace(/ /g,'').match(/^[A-CEGHJ-PR-TW-Z]{1}[A-CEGHJ-NPR-TW-Z]{1}[0-9]{6}[A-D]{1}$/i);
}, 'Please specify a valid national insurance number');
Edit: Andrew Bauer modified my answer to add checks for allowed/disallowed characters that were unknown at the time I answered. You should up-vote his answer since it is more complete and apparently performs better validation.
If you can't just remove all the whitespace first, this should work:
^\s*[a-zA-Z]{2}(?:\s*\d\s*){6}[a-zA-Z]?\s*$
Explanation:
^ # beginning of string
\s* # optional leading whitespace
[a-zA-Z]{2} # match two letters
(?:\s*\d\s*){6} # six digits, with optional whitespace leading/trailing
[a-zA-Z]? # zero or one letter
\s* # optional trailing whitespace (just in case)
$ # end of string
I found a link to the government xml document which contains the regular expression for validating national insurance which was:
[A-CEGHJ-NOPR-TW-Z]{2}[0-9]{6}[ABCD\s]{1}
I've done some testing on regex online and seems to work well and in only 4 steps.
https://web.archive.org/web/20121026141031/http://webarchive.nationalarchives.gov.uk/+/http://www.cabinetoffice.gov.uk/media/291296/CitizenIdentificationTypes-v1-4.xml