Module: Irxrb::RangeToRegex

Defined in:
lib/irxrb/range_to_regex.rb

Class Method Summary collapse

Class Method Details

.invoke(range) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/irxrb/range_to_regex.rb', line 5

def invoke(range)
  max = range.max + 1
  min = range.min
  pivot = pivot(min, max)

  ret = []

  base = pivot
  split_by_unit(max - pivot).each do |unit, diff|
    ret << make_regex(base, unit, diff)
    base += unit * diff
  end

  base = pivot
  split_by_unit(pivot - min).each do |unit, diff|
    ret.unshift make_regex(base, unit, -diff)
    base -= unit * diff
  end

  /#{ret.join('|')}/
end

.make_regex(base, unit, diff) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/irxrb/range_to_regex.rb', line 57

def make_regex(base, unit, diff)
  if diff < 0
    return make_regex(base + unit * diff, unit, -diff)
  end
  prefix = base / (unit * 10)
  prefix_str = prefix == 0 ? '' : prefix.to_s
  current = base / unit % 10
  current_str = diff == 1 ? current.to_s : "[#{current}-#{current + diff - 1}]"
  suffix_str = "[0-9]" * Math.log(unit, 10).round
  return prefix_str + current_str + suffix_str
end

.pivot(min, max) ⇒ Object



47
48
49
50
51
52
53
54
55
# File 'lib/irxrb/range_to_regex.rb', line 47

def pivot(min, max)
  unit = unit_of(max)
  pivot = max / unit * unit
  while unit > 1 && (min / pivot) == 1
    unit /= 10
    pivot = max / unit * unit
  end
  return pivot
end

.split_by_unit(num) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/irxrb/range_to_regex.rb', line 35

def split_by_unit(num)
  ret = []
  unit = 1
  while num > 0
    n = num % 10
    ret.unshift [unit, n] if n != 0
    unit *= 10
    num /= 10
  end
  return ret
end

.unit_of(num) ⇒ Object



27
28
29
30
31
32
33
# File 'lib/irxrb/range_to_regex.rb', line 27

def unit_of(num)
  unit = 1
  loop do
    return unit if num < unit * 10
    unit *= 10
  end
end