1

I am trying to validate numbers which are allowed to belong to multiple ranges. e.g.:

A number x is valid if it lies between 150-200, or 700-750

Basically I want to store these restrictions in a database, so I thought storing them as regexes would be a nice way of handling this problem.

I am new to regular expressions, so am not being able to come up with one for the above validation.

shiladitya
  • 2,290
  • 1
  • 23
  • 36
  • 1
    Regex just isn't *a nice way of handling this problem*... you're using a DBMS, stick to the tools already in the DB... regex is slow. If you're using SQL, check this http://stackoverflow.com/questions/1736630/sql-constraint-minvalue-maxvalue ... otherwise, tag your DBMS – Mariano Oct 06 '15 at 18:50
  • 1
    @Mariano being slow may not be main problem. If ranges will be more complex creating and maintaining regex will be nightmare: http://stackoverflow.com/a/20793792/1393766 – Pshemo Oct 06 '15 at 18:53
  • @Pshemo I know, I've gone that way just for fun. Of course, you can always [cheat](http://utilitymill.com/utility/Regex_For_Range) – Mariano Oct 06 '15 at 18:55
  • @Mariano How do you think I create regex for that answer ;) (too bad that site is off-line now). – Pshemo Oct 06 '15 at 18:56
  • @Pshemo ah, I just saw the link in your post. :-) – Mariano Oct 06 '15 at 18:58

1 Answers1

2

Solution:

1[5-9][0-9]|200|7[0-4][0-9]|750

Explanation:

Since you have a very well defined ranges, the regex is fairly simple.

It can be broken up into two parts:

  1. 150 through 199 OR 200
  2. 700 through 749 OR 750

So, put together the regex will read as

((150 through 199 OR 200) OR (700 through 749 OR 750))

Your first number is 150, so we will have to match a '1' for the first digit followed by the range for the second digit which could be 5 though 9 (you don't want anything less that 150, so 4 and less are out) and also followed by the range for the third digit which could be anything from 0 to 9. This captures all numbers from 150 to 199.

The last number in the first range is 200, so we can just look for that. It is too different from the rest of the possibilities in the range, thus it is easier to look for specifically for it instead of trying to think of a complex way of including it in a regex range.

The second range follows the same patten but with different numbers. Again, we are looking for most of the numbers by using the regex range and looking for the last number, 750, specifically since it is too different -- has a number 5 in the middle. If we include 5 in the middle regex range, it will go up to 759, which is outside of the scope.

Finally, OR both parts and the regex is ready.

Adjust for your input. You may need to surround it with ^ and $ for the beginning and the end of the line or if your input has other text surrounding the number in question, expand your regex to deal with it appropriately.

keda
  • 559
  • 2
  • 12
  • 4
    While this regex may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – JAL Oct 06 '15 at 20:32
  • You may want to anchor it to `^` and `$` to avoid matching other numbers – Mariano Oct 06 '15 at 22:03
  • 1
    @JAL Good point. The explanation is now provided in the answer. – keda Oct 06 '15 at 23:40
  • @Mariano You are assuming the number is on its own line. I deliberately stayed away from surrounding the regex with anything. The answer responds to shiladitya's specific question. He didn't provide any more specifics, so assumptions about his input could make the answer unnecessarily complicated and confusing. – keda Oct 06 '15 at 23:48
  • 1
    @keda Any anchors should suffice, either line, boundary or lookarounds, in order to avoid the undesired result: 'why is it matching the subject `"1200"`'. You did clarify that point with your last edit though. – Mariano Oct 07 '15 at 00:15