I have an Asp.Net website and I want to use a RegularExpressionValidator to check if a UK postcode is English (i.e. it's not Scottish, Welsh or N.Irish).
It should be possible to see if the postcode is English by using just the letters from the first segmant (called the Postcode Area). In total there are 124 postcode areas and this is a list of them.
From that list, the following postcode areas are not in England.
The input to the regex may be the whole postcode, or it might just be the postcode area.
Can anyone help me create a regular expression that will match only if a given postcode is English?
EDIT - Solution
With help from several posters I was able to create the following regex which i've tested against over 1500 testcases successfully.
^(AL|B|B[ABDHLNRS]|C[ABHMORTVW]|D[AEHLNTY]|E|E[CNX]|FY|G[LUY]|H[ADGPUX]|I[GMP] |JE|KT|L|L[AENSU]|M|ME|N|N[EGNRW]|O[LX]|P[ELOR]|R[GHM]|S|S[EGKLMNOPRSTW]|T[AFNQ RSW]|UB|W|W[ACDFNRSV]|YO)\d{1,2}\s?(\d[\w]{2})?
I've already answered once, making the point that it's not possible to come up with a 100% correct England-only regex (since the postcode areas don't lie along political boundaries).
However I've dug a bit deeper into this, and ... well it is possible, but it's a lot of work.
To verify an England-only postcode, you need to exclude the non-English postcodes. The easy ones are:
(I'm not going to mention UK-style postcodes for territories outside the UK, like St Helena, Gibraltar etc. Technically speaking, the Isle of Man and Channel Islands aren't part of the UK either, but they're much nearer by, and more closely tied into the Royal Mail system in the UK.)
The purely Scottish postcode areas are (as you mentioned):
ZE,KW,IV,HS,PH,AB,DD,PA,FK,G,KY,KA,EH,ML
DG and TD are nominally Scottish, and are for the most part in Scotland. However some areas extend over the Scotland-England border as follows:
The breakdown is as follows:
DG16 is in Scotland except for the following English postcodes:
TD9 is in Scotland except for TD9 0T[JPRSTUW]
TD12 has only one sector (TD12 4), which is spread roughly half and half across England and Scotland:
TD15 is the most complicated. There are 3 sectors, of which TD15 2 and TD15 9 are entirely in England.
TD15 1 is split across England and Scotland.
Postcodes beginning as follows are in Scotland:
... except for these English postcodes:
All other postcodes in TD15 1 are in England, except for those beginning as follows:
... which are all in England, with the exception of the following postcodes which are in Scotland:
The English postcode areas CA and NE lie on the other side of the England-Scotland border, however they never extend into Scotland.
In fact, the last two letters of a UK postcode is based on how the postman actually delivers post (as far as I'm aware), so it's not given for granted that it will fall inside a political boundary. Thus if there's a group of houses which straddle the border, then it's possible that the entire postcode (i.e. at the most fine-grained level) does not lie entirely within either England or Scotland. E.g. TD9 0TJ and TD15 1UZ are very close to the border, and I don't really know for sure if they're entirely on one side or not.
The England-Wales border is also complicated, however I'll leave this as an exercise for the reader.
There are 124 Postcode Areas in the UK.
-- PAF® statistics August 2012, via List of postcodes in the United Kingdom (Wikipedia).
I recommend breaking your problem down into two parts (think functions):
Is the postcode valid?
UK Postcode Regex (Comprehensive)
Is the postcode English?
This can be broken down further:
! /^(ZE|KW|IV|HS|PH|AB|DD|PA|FK|G|KY|KA|DG|TD|EH|ML)[0-9]/
! /^(LL|SY|LD|HR|NP|CF|SA)[0-9]/
Note that the syntax will vary according to your programming language. Doing all this in one regular expression would soon become unmanageable.
It's not possible to come up with an England-only regex, because the postcode areas don't lie along political boundaries, at least not at the postcode area or district level.
For example, CH1 is in England, and CH5 is in Wales.
At the postcode district level there are still problems, for example TD12 is half in England, half in Scotland.
The only area which you can rely on is BT (Northern Ireland)
Use ^(AB|AL|B| ... )$
, where the ... is where you fill the rest of the valid ones in, separated by pipes (|
).
EDIT: There's a boatload of information here: http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom
If you were to include the in/out codes, it would be something like ^(AB|AL|B| ... )([\d\w]{3})\s([\d\w]{3})$
, which would get the rest of the code.
EDIT
^(A[BL]|B[ABDHLNRST]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[CNX]?|F[KY]|G[LUY]|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|T[AFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)([\w\d]{1,2})\s?([\w\d]{3})$
Part of this regex is taken from another one of the answers. It matches the valid postcodes, then 1 to 2 {1,2}
letters \w
or numbers \d
, an optional space \s?
, then 3 letters or numbers. Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With