in reply to Matching data against non-consecutive range

The ranges in /[]/ are character ranges. Not numbers. What's between [] always matches one character. Never zero. Never more than one. So, if you have /[10-450]/, you are matching either a 1, a character between 0 and 4 (inclusive), a 5 or a 0. Which basically means 0, 1, 2, 3, 4 or 5.

How to best match in ranges like this depends. It depends on how many matches you are doing (the more, the more time you can spend on doing preprocessing), the number of ranges, and the size of ranges. A couple of techniques (some already been presented):

  1. Put all the different numbers in a hash. This gives fast lookup times, but if the ranges are large, this takes a lot of preprocessing time and memory. Doesn't work if both the endpoints and querypoints are reals instead of integers.
  2. Iterate over the ranges, testing whether the querypoint falls between the endpoints. This gives a simple algorithm, but the querytime is linear in the number of ranges. Not so good if you have a lot of ranges and a lot of queries to perform. If you have just one query to do, this is the way to go.
  3. Binary search over the endpoints. Reasonably fast lookup times (O(log R), with R the number of ranges), so if you have a lot of lookups, this maybe the way to go. Tricky to get right if there are overlapping ranges. Doesn't allow for easy adding or deleting ranges.
  4. Segment tree. Basically a binary search tree on the ranges. More code, but same efficiency as a normal binary search. Allows for efficient adding/deleting ranges. Useful if you have a lot of ranges, do a lot of queries, and if your set of ranges isn't static.