4

Can someone tell me how to match a number between 1-17 with a regex:

I tried [1-9]|1[0-7] but it matches 8 in the 18 for example because of the first part.

Any ideas? I don't want to have leading zeros.

edited:

The problem is I'm trying to validate a UK postcode like to start with:

KW1-17 (it could be KW1, KW2 up to KW17) ... and this is just the outward part. The postcode may be KW15 1BM or KW151BM so I can't just use anchors to match the whole string ... it becomes more complicated.

Ilian Andreev
  • 1,071
  • 3
  • 12
  • 18
  • This might help you as well: http://stackoverflow.com/questions/164979/uk-postcode-regex-comprehensive – 03Usr Jul 15 '12 at 10:38

1 Answers1

10

You need to put anchors around the regex or it will match substrings:

^(?:[2-9]|1[0-7]?)$

I've also taken the liberty to make your regex a bit more efficient:

Comparison of two regexes

Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
  • I am just wondering how this is more efficient? What tests did you run to determine this? – AlanFoster Jul 13 '12 at 09:25
  • @AlanFoster: It avoids backtracking on numbers 10-17. In the original regex, the first part of the alternation would match the 1, then the match would fail because the `$` could not be matched, therefore the engine has to backtrack into the second part of the alternation to succeed. By removing the `1` from the first part, that backtracking is no longer necessary. – Tim Pietzcker Jul 13 '12 at 09:37
  • @AlanFoster: I've added a RegexBuddy debugging screenshot to visualize this. – Tim Pietzcker Jul 13 '12 at 09:44
  • 1
    I never knew that program existed. I've upvoted you for your answer being useful to me. Thanks – AlanFoster Jul 13 '12 at 11:25
  • Instead of `^` and `$`, you could use `(?<!\d)` and `(?!\d)` to ensure that it's not preceded or followed by a digit. This assumes that the flavour of regex you're using supports lookbehind and lookahead. – MRAB Jul 13 '12 at 15:56