Regular Expression to validate UK National Insurance Number

Actually, NIN doesn't allow D, F, I, Q, U or V for the first two letters and doesn't allow O for the second letter; on top of this, the prefix letters can not be BG, GB, NK, KN, TN, NT and ZZ. Also the suffix letter is either A, B, C or D, but may be represented by a space if unknown. - http://en.wikipedia.org/wiki/National_Insurance_number#Format

As such, a more valid check would be (I have only supplied a version with capital letters, can easily be altered for lower-case):

^(?!BG)(?!GB)(?!NK)(?!KN)(?!TN)(?!NT)(?!ZZ)(?:[A-CEGHJ-PR-TW-Z][A-CEGHJ-NPR-TW-Z])(?:\s*\d\s*){6}([A-D]|\s)$

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

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');