0

I need to test a string and make sure its a valid UK postcode.

My code currently works like this:

var re = /GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|BX|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}/;
console.log(re.test('WD4 9PL'));

Which returns true.

But, if I add extra text after PL it also returns true:

var re = /GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|BX|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}/;
console.log(re.test('WD4 9PL TEST'));

The second should return false, how can this be accomplished?

CharliePrynn
  • 3,034
  • 5
  • 40
  • 68

1 Answers1

3

Wrap your regex in ^ and $ to ensure that full string is matched:

var re = /^(GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|BX|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4})$/;
console.log(re.test('WD4 9PL'));

^ matches beginning of the line

$ matches end of the line

Note, I've also wrapped it in ():

/^abc|def$/ will match abc.... and ....def

/^(abc|def)$/ will match only abc or def

Example:

> /abc/.test("abcd")
true
> /^abc$/.test("abcd")
false
> /^abc$/.test("abc")
true
mishik
  • 9,973
  • 9
  • 45
  • 67
  • If you test re.test('WD4 9PL TESt'), this still returns true. – CharliePrynn Jul 23 '13 at 15:42
  • Just did: `re.test('WD4 9PL TESt') -> false` – mishik Jul 23 '13 at 15:43
  • In case you're confused, `^` means "the string **must** start the match here" and `$` means "the string **must** end the match here". `/[0-9]+/` would match any string with a number in *somewhere*, whereas `/^[0-9]+/` would **only** match strings **starting** with any amount (1+) of numbers. – h2ooooooo Jul 23 '13 at 15:44
  • Thanks Mishik, just noticed your edit adding brackets, returns false now. – CharliePrynn Jul 23 '13 at 15:46