Search code examples
regexpostal-code

Regex to match the first half of a UK postcode


I need a regex to match the first half of a uk postcode, and it's possible just one half or a full post code could get passed in.

There is great way to match full postcode here: UK Postcode Regex (Comprehensive)

However I need to just get the first 3 or 4 characters of a postcode, with the possibility of half a post code or a postcode without spaces getting passed in, so any of these:

SL4 4BZ
SL44BZ - this will pull out just 'SL4'
SL4
DY10
DY10 3BD
DY10 3BD

The regex needs to match:

  • if it's 5 characters long (excluding spaces), remove last 3 characters and the first 2 remaining characters are the half-a-postcode
  • if it's 6 characters long (excluding spaces), remove last 3 characters and the first 3 remaining characters are the half-a-postcode
  • if it's 7 characters long (excluding spaces), remove last 3 characters and the first 4 remaining characters are the half-a-postcode
  • if it's 2, 3 or 4 characters long, keep it

But I can't quite get my head around how to write something this complex.


Solution

  • Updated for 2/5 characters as well, total coverage = 2/5 or 3/6 or 4/7

    This works for the input samples.
    Here are 2 variations of the same thing.

    Results in Capture group 1

     #  (?m)^([A-Z0-9]{2,4})(?:\s*[A-Z0-9]{3})?$
    
     (?m)
     ^ 
     (                             # (1 start)
          [A-Z0-9]{2,4} 
     )                             # (1 end)
     (?: \s* [A-Z0-9]{3} )?
     $ 
    

    Results in Capture group 0

     # (?m)^[A-Z0-9]{2,4}(?=(?:\s*[A-Z0-9]{3})?$)
    
     (?m)
     ^ 
     [A-Z0-9]{2,4} 
     (?=
          (?: \s* [A-Z0-9]{3} )?
          $ 
     )
    

    @Smickie - Update - Regarding your question about inline-modifiers in JS.
    (I'm not a JS expert but here is a simple example)
    I don't believe inline modifiers construct are available. However, they can be added
    via the flags parameter (enum) or in the /../flags notation.

    You can see this example work in JSfiddle here --> http://jsfiddle.net/cdcv8uug/

    var teststr = "SL\nSL 4BZ\nSL4BZ\nSL4\nSL4 4BZ\nSL44BZ\nDY10\nDY10 3BD\nDY10 3BD";
    
    var arr = teststr.match( /^[A-Z0-9]{2,4}(?=(?:\s*[A-Z0-9]{3})?$)/mg );
    
    var res = "Using match() -> Capture group 0\nteststr.match(/^[A-Z0-9]{2,4}(?=(?:\s*[A-Z0-9]{3})?$)/mg)\n";
    for (var index = 0; index < arr.length; index++)
    {
       res += index + ":  " +  arr[index] + "\n";
    }
    
    var re = /^([A-Z0-9]{2,4})(?:\s*[A-Z0-9]{3})?$/mg;
    res += "\nUsing exec() -> Capture group 1\nvar re = /^([A-Z0-9]{2,4})(?:\s*[A-Z0-9]{3})?$/mg;\nre.exec(teststr)\n";
    
    index = 0;
    while ((arr = re.exec(teststr)) != null)
    {
        res += index + ":  " + arr[1] + "\n";
        index++;
    }
    
    alert( res );