6

Possible Duplicate:
UK Postcode Regex (Comprehensive)

I have the following code for validating postcodes in javascript:

function valid_postcode(postcode) {
    postcode = postcode.replace(/\s/g, "");
    var regex = /[A-Z]{1,2}[0-9]{1,2} ?[0-9][A-Z]{2}/i;
    return regex.test(postcode);
}

Tests:

CF47 0HW - Passes - Correct
CF47 OHW - Passes - Incorrect

I have done a ton of research but can't seem to find the definitive regex for this common validation requirement. Could someone point me in the right direction please?

Community
  • 1
  • 1
dai.hop
  • 741
  • 3
  • 11
  • 14
  • I have used this tester: http://www.regular-expressions.info/javascriptexample.html and your provided example worked as expected. First one passed, second not. – jnovacho Dec 20 '12 at 10:05
  • @willemD'haeseleer I have already dismissed that script because in my opinion, it is unnecessarily large. – dai.hop Dec 20 '12 at 10:21
  • @jnovacho I'm getting 'No match' for both examples in Safari 6. – dai.hop Dec 20 '12 at 10:24

3 Answers3

8

Make your regex stricter by adding ^ and $. This should work:

function valid_postcode(postcode) {
    postcode = postcode.replace(/\s/g, "");
    var regex = /^[A-Z]{1,2}[0-9]{1,2} ?[0-9][A-Z]{2}$/i;
    return regex.test(postcode);
}
paulgrav
  • 614
  • 3
  • 7
  • 6
    This does not allow for numerous London postcodes, e.g. Downing Street is SW1A 2AA and Buckingham Palace is SW1A 1AA. Try: `const regex = /^[A-Z]{1,2}[0-9]{1,2}[A-Z]{0,1} ?[0-9][A-Z]{2}$/i;` instead. – colincclark Nov 03 '16 at 06:41
8

You want a 'definitive regex' - given all the permutations of the UK postcodes, it needs to be therefore 'unnecessarily large'. Here's one I've used in the past

"(GIR 0AA)|((([ABCDEFGHIJKLMNOPRSTUWYZ][0-9][0-9]?)|(([ABCDEFGHIJKLMNOPRSTUWYZ][ABCDEFGHKLMNOPQRSTUVWXY][0-9][0-9]?)|(([ABCDEFGHIJKLMNOPRSTUWYZ][0-9][ABCDEFGHJKSTUW])|([ABCDEFGHIJKLMNOPRSTUWYZ][ABCDEFGHKLMNOPQRSTUVWXY][0-9][ABEHMNPRVWXY])))) [0-9][ABDEFGHJLNPQRSTUWXYZ]{2})"

Notice I never just use A-Z, for instance, because in each part there are always certain letters excluded.

duncan
  • 31,401
  • 13
  • 78
  • 99
  • This is correct, but is also a bit of duplication. This is already answered in the following question http://stackoverflow.com/questions/164979/uk-postcode-regex-comprehensive – Mark Withers Dec 20 '12 at 10:44
  • Indeed, I'd posted my answer before I'd read the question you linked to in yours. Suggest question is therefore a duplicate – duncan Dec 20 '12 at 10:57
1

The problem is the first line of your function. By trimming the spaces out of the target string, you allow false positives.

CF47OHW will match [A-Z]{1,2}[0-9]{1,2} ?[0-9][A-Z]{2}

CF matches [A-Z]
4 matches [0-9]{1,2}
(blank) matches \s?
7 matches [0-9]
OH matches [A-Z]{2}
W gets discarded

So, as Paulgrav has stated, adding the start and end characters (^ and $) will fix it.

At that point, you can also remove the \s? bit from the middle of your regex.

However! Despite the bug being fixed, your regex is still not going to work how you'd like it to. You should look at the following rather good answer on this here site UK Postcode Regex (Comprehensive)

Community
  • 1
  • 1
Mark Withers
  • 1,462
  • 5
  • 16
  • 34