Skip to content

Instantly share code, notes, and snippets.

@Pablo-R
Created September 27, 2017 12:50
Show Gist options
  • Save Pablo-R/6155e9acb258fb9cd8c3161db9b0d3b0 to your computer and use it in GitHub Desktop.
Save Pablo-R/6155e9acb258fb9cd8c3161db9b0d3b0 to your computer and use it in GitHub Desktop.
Integer Regexp Builder
class RangeBuilder
def initialize(min_value, max_value)
@min_value = min_value
@max_value = max_value
end
def self.generate_forward_ranges(min_range_value)
temp_max_range = ""
left_range_char_list = min_range_value.to_s.reverse.chars
left_range_char_list.each_with_index do |char, idx|
if char == '0'
temp_max_range << '9'
else
temp_max_range << '9'
next_number = (left_range_char_list[(idx+1)..left_range_char_list.size]).join("")
temp_max_range << next_number if next_number.to_s =~ /[1-9]/
break
end
end
new_range = new(min_range_value.to_s, temp_max_range.reverse)
[new_range, (new_range.get_end).to_i + 1]
end
def self.generate_backward_ranges(right)
temp_min_range = ""
right_range_char_list = right.to_s.reverse.chars
right_range_char_list.each_with_index do |char, idx|
if char == '9'
temp_min_range << '0'
else
temp_min_range << '0'
next_number = right_range_char_list[(idx+1)..right_range_char_list.size].join("")
temp_min_range << next_number if next_number =~ /[1-9]/
break
end
end
new_range = new(temp_min_range.reverse, right.to_s)
[new_range, (new_range.get_start).to_i - 1]
end
def intersect?(range)
(get_end > range.get_start && range.get_end > get_start)
end
def merge_two_ranges(range)
RangeBuilder.new(get_start, range.get_end)
end
def get_end
@max_value
end
def get_start
@min_value
end
end
#!/usr/bin/ruby
require_relative 'range_builder'
class Regexp
def self.build(*arguments)
array_args = *arguments
string = "\\A("
array_args.each_with_index do |expr, index|
if expr.is_a? Range
string += self.build_range_string_with(expr.min, expr.max)
else
next_expr = array_args[index+1]
string += (!next_expr.nil?) ? expr.to_s.concat('|') : expr.to_s
end
end
Regexp.new(string.concat(")\\z"))
end
def self.build_range_string_with(min_range, max_range)
result_array = []
left_range_list = self.build_left_side_of_range_with(min_range, max_range)
left_range_list_last_element = left_range_list.pop
result_array.concat(left_range_list)
right_range_list = self.build_right_side_of_range_with(left_range_list_last_element.get_start.to_i, max_range)
right_range_list_first_element = right_range_list.shift
if left_range_list_last_element.intersect?(right_range_list_first_element)
result_array.push(left_range_list_last_element.merge_two_ranges(right_range_list_first_element))
else
result_array.push(left_range_list_last_element)
result_array.push(right_range_list_first_element)
end
self.regex_range_builder(result_array.concat(right_range_list))
end
private
def self.build_left_side_of_range_with(min, max)
left_array = []
while min < max
a_new_left_range, min = RangeBuilder.generate_forward_ranges (min)
left_array.push(a_new_left_range)
end
left_array
end
private
def self.build_right_side_of_range_with(min, max)
right_array = []
while max > min
a_new_right_range, max = RangeBuilder.generate_backward_ranges (max)
right_array.unshift(a_new_right_range)
end
right_array
end
private
def self.regex_range_builder(array)
string = ""
array.each do |range|
(range.get_end.size).times do |idx|
if range.get_start[idx] == range.get_end[idx]
string.concat(range.get_end[idx])
else
string.concat("[#{range.get_start[idx]}-#{range.get_end[idx]}]")
end
end
string.concat("|")
end
string.chomp("|")
end
end
lucky = Regexp.build(3..7)
puts "4 => (3..7) #{!!("4" =~ lucky)}"
no_match = Regexp.build(3,7,25..135)
puts "136 => (3,7,25..135) #{!!("136" =~ no_match)}"
a_match = Regexp.build(26..27)
puts "26 => (26..27) #{!!("26" =~ a_match)}"
day = Regexp.build(1..31)
puts "Tues => (1..31) #{!!("Tues" =~ day)}"
puts "6 => (1..31) #{!!("6" =~ day)}"
puts "16 => (1..31) #{!!("16" =~ day)}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment