Naresh
Naresh

Reputation: 2673

Regular Expression for UK postcodes

I have a list of post codes which should be excluded from my shipping methods.

Suppose I have to exclude Scilly Isles, Isle of Man and few others.

For the above 2 areas valid post codes are IM1-IM9, IM86, IM87, IM89. And if it is IM25 or IM85 it is invalid.

I have writtent following expression. But it is returning even it is IM25 or IM 85.

var regex = new Regex("(PO3[0-9]|PO4[0-1]|GY[1-9]|JE[1-5]|IM[1-9]|TR[1-9])");

If I am passing IM85, to my expression it should return false. for IM1-IM9,, IM86, IM87, IM89 it should return true.

Same with TR post codes also. TR1-TR27 is a valid post code. If I give TR28, it should return false.

I am using '|' to seperate multiple patterns. Is that the right way of including multiple patterns in 1 expression.

Upvotes: 1

Views: 882

Answers (4)

Naresh
Naresh

Reputation: 2673

I have changed my approach.

Instead of going for a regular expression which is becoming more complex, I am saving all the excluded outward codes of UK post codes.

And if any post code contains the particular outward code, excluding the post code from the list. Outward codes are in this format

XX-YYY
XXX-YYY
XXXX-YYY

In all above formats, X represents outward code of an UK postcode.

Upvotes: 0

craig1231
craig1231

Reputation: 3877

The actual validation is on the wikipedia site... Google has the answers ;) http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation

(GIR 0AA)|(((A[BL]|B[ABDFHLNRSTX]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[HNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTY]?|T[ADFNQRSW]|UB|W[ADFNRSV]|YO|ZE)[1-9]?[0-9]|((E|N|NW|SE|SW|W)1|EC[1-4]|WC[12])[A-HJKMNPR-Y]|(SW|W)([2-9]|[1-9][0-9])|EC[1-9][0-9]) [0-9][ABD-HJLNP-UW-Z]{2})

Upvotes: 1

Suamere
Suamere

Reputation: 6258

I still think you need more clarification. As a huge Regex guy, I would like to point out that multi-digit ranges should try to be put into the code side, not the Regex side, just for your sanity. But I personally like to play with Regex in this way. Regex reads one character at a time, so it only recognizes zero through nine. Not ten, not twenty eight. If you want to allow the following:

28 through 347

Then it becomes pretty complicated. To put it into words, you want to allow:

    If Two Digits, allow 2-9 for the first digit, and:
      If the first digit is a Two, then allow 8/9 for the second digit,
      ElseIf the first Digit is 3-9, then allow 0-9 for the second digit
    Elseif Three Digits, allow 1-3 for the first Digit, and:
      If the first digit is a Three, then allow 0-4 for the second digit, and:
        If the second digit is a Four, then allow 0-7 for the third digit, 
        ElseIf the second digit is 0-3, then allow 0-9 for the third digit.
      ElseIf the first digit is 1/2, then allow 0-9 for both the Second and Third digits.

Then with that, you can write a proper Regex like so, which searches for a word boundary or non-Digit surrounding a 2-pair or 3-pair. With this type of Problem-Solving, you should be able to figure out your Regex issue. Otherwise, let us know more about EXACTLY What you want to Match and NOT Match:

(\b|\D)((2[89]|[3-9][0-9])(\b|\D)|(3(4[0-7]|[0-3][0-9])|[12][0-9][0-9])(\b|\D))

Upvotes: 0

stema
stema

Reputation: 93086

What do you expect? What should be matched and what not? And please give an example of the string you want to test.

If you match your pattern against "IM25" it will match because you do allow IM[1-9] in your pattern, so you get a valid partial match. If you want to avoid that (I am not sure what you want to achieve) and want to allow really only a single digit after the first letters, use a "word boundary" \b and specify exactly what you want to allow, something like this:

(PO3[0-9]|PO4[0-1]|GY[1-9]|JE[1-5]|IM([1-9]|8[6-9])|TR([1-9]|2[0-7]))\b

See it here on Regexr

this would allow for the "IM" part also 6-9 as a second digit when there is a 8 before.

Update

It is still not clear what the context of your task is. I assume you have a list of valid Postcodes, probably it would be better, you extract the post code or only the first part of it (for that you can eventually use a regex) and check if it is in the list or not.

Upvotes: 1

Related Questions