Skip to content

Instantly share code, notes, and snippets.

@havenwood
Created November 28, 2015 21:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save havenwood/fe4efe47604b32214a60 to your computer and use it in GitHub Desktop.
Save havenwood/fe4efe47604b32214a60 to your computer and use it in GitHub Desktop.
Looking for patterns matching numeric ranges with regex
module Match
module_function
def range_upto n
s = n.to_s.freeze
ones = s[-1].to_i
tens = s[-2].to_i
hundreds = s[-3].to_i
if n < 0
raise NotImplementedError, 'Negatives :O'
elsif n == 0
/\A0\z/
elsif n <= 9
/\A[0-#{n}]\z/
elsif n <= 19
/\A(1[0-#{ones}]|\d)\z/
elsif n <= 99
/\A(#{tens}[0-#{ones}]|[1-#{tens.pred}]?\d)\z/
elsif n <= 199
if tens.zero?
/\A(1[0-#{tens}][0-#{ones}]|[1-9]?\d)\z/
else
/\A(1[0-#{tens}][0-#{ones}]|1[0-#{tens.pred}]\d|[1-9]?\d)\z/
end
elsif n <= 999
if tens.zero?
/\A([1-#{hundreds}][0-#{tens}][0-#{ones}]|[1-#{hundreds.pred}]\d{2}|[1-9]?\d)\z/
else
/\A([1-#{hundreds}][0-#{tens}][0-#{ones}]|#{hundreds}[0-#{tens.pred}]\d|[1-#{hundreds.pred}]\d{2}|[1-9]?\d)\z/
end
else
raise NotImplementedError, 'More than three digits :O'
end
end
end
require 'minitest/autorun'
describe Match do
it 'accepts upto the max' do
0.upto 999 do |n|
r = Match.range_upto(n)
0.upto n do |x|
assert x.to_s =~ r, "#{r.inspect} for `#{n}` doesn't match \"#{x}\""
end
end
end
it 'rejects one over the max' do
0.upto 999 do |n|
r = Match.range_upto(n)
assert n.next.to_s !~ r, "#{r.inspect} matches \"#{n.next}\" when `#{n}` is max"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment