1

I have tried the one on the .gov website, as stated on many questions here, but it doesnt seem to work for short postcodes.

My regex:

preg_match('^(([gG][iI][rR] {0,}0[aA]{2})|((([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y]?[0-9][0-9]?)|(([a-pr-uwyzA-PR-UWYZ][0-9][a-hjkstuwA-HJKSTUW])|([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y][0-9][abehmnprv-yABEHMNPRV-Y]))) {0,}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2}))^', $this->post['location'], $matches)

When I use a long postcode of format: AA9 9ZZ it works, but one of format AA9 doesnt. I need the following formats to work:

  • AA9
  • AA99
  • AA9 9ZZ
  • AA99 9ZZ
Ryan Hipkiss
  • 648
  • 1
  • 7
  • 20
  • First, don't use `^` as pattern delimiter, and use it with `$` to anchor your pattern. Replace capture groups with non-capturing groups, use the i flag, remove useless groups. – Casimir et Hippolyte Dec 05 '16 at 11:52
  • @CasimiretHippolyte ive changed that now, the regex appears to be validating long postcodes, but not the shortened versions.. – Ryan Hipkiss Dec 05 '16 at 11:55
  • It is only the first step of the job (to make it more readable in particular), not the solution. – Casimir et Hippolyte Dec 05 '16 at 12:06
  • Also, if other solutions do not work for you, try `'~^(?:gir\ *0a{2}|(?:[a-pr-uwyz][a-hk-y]?[0-9][0-9]?|(?:[a-pr-uwyz][0-9][a-hjkstuw]|[a-pr-uwyz][a-hk-y][0-9][abehmnprv-y]))(?:\ *[0-9][abd-hjlnp-uw-z]{2})?)$~i'`, see https://regex101.com/r/6PBlmu/1 – Wiktor Stribiżew Dec 05 '16 at 12:14

4 Answers4

0

^[A-Z]{1,2}\d{1,2}(?:(?: )?\d[A-Z]{2})?$ is the pattern I could come up with and it seems to work.

This could probably be improved, though. I'm not a Regexpert.

Here's a live example

ThePerplexedOne
  • 2,920
  • 15
  • 30
0

According to the pattern you have given and making the second part optional, I obtain:

~^(?:gir(?: *0aa)?|[a-pr-uwyz](?:[a-hk-y]?[0-9]+|[0-9][a-hjkstuw]|[a-hk-y][0-9][abehmnprv-y])(?: *[0-9][abd-hjlnp-uw-z]{2})?)$~i

demo

or to make it more readable:

~ # pattern delimiter
^ # start of the string anchor
(?: # branch 1
    gir
    (?:[ ]*0aa)? # second part optional (branch 1)
  | # branch 2
    [a-pr-uwyz] # I put it in factor to shorten the pattern
    (?:
        [a-hk-y]?[0-9]+
      |
        [0-9][a-hjkstuw]
      |
        [a-hk-y][0-9][abehmnprv-y]
    )
    (?:[ ]*[0-9][abd-hjlnp-uw-z]{2})? # second part optional (branch 2)
)
$ # end of the string anchor
~ix
Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
0

Due to the way UK postcodes work, validating them by using regex is not a foolproof solution. Two of the main problems are:

  • Royal Mail could change the format of some postcodes, adding sub-districts that isn't covered by the regex you choose to use.
  • Validating by regex only ensures the postcode is in a valid format according to your regex rules, not that it's a postcode that exists as part of an address.

Royal Mail provide a PAF Database, which contains all UK addresses, including postcodes. Many companies have exposed this data through APIs and website plugins.

For example, I work for a company called PCA Predict, and we have a demo of our solution in action. It's a plugin for online checkout forms that allows a customer to start typing any part of their address, and will auto fill the fields when they select their's.

We also offer REST APIs to silently validate and return addresses.

Please feel free to comment if you need any help with address validation, as it can be much harder than it initially looks! I'm also not saying you should use our services, but give it a go, and have a Google about other options as well.

HenrikV
  • 401
  • 1
  • 4
  • 6
0

I have had the same problem and it is hard to validate a postcode, Royal Mail Add and Remove postcodes quite frequently. so for the past 2 weeks I have been building an address database and have created a very nasty looking API for free you can validate Postcode and it will return every address for that postcode.

I hope this is helpful.

https://www.pervazive.co.uk/free-api-for-uk-postcode-lookup/

Endpoint

GET: https://api.pervazive.co.uk/postcode.php?postcode=[POSTCODE]

Response

Request GET: -> https://api.pervazive.co.uk/postcode.php?postcode=AB10+1AB

Return Format: JSON

{"predictions":[
{"ID":"0","Address":"Aberdeen City Council, Marischal College, Broad Street, Aberdeen, Aberdeenshire, AB10 1AB","Postcode":"AB10 1AB"}
],"Execution_Time":"0.50983214378357","status":"200"}