class Pxeger
Constants
- ALL
- CLASSES
- DIGITS
- LOWERS
- OTHERS
- SPACES
- UPPERS
- VERSION
Public Class Methods
new(pattern)
click to toggle source
# File lib/pxeger.rb, line 6 def initialize(pattern) @pattern = pattern.instance_of?(Regexp) ? pattern.source : pattern end
Public Instance Methods
generate()
click to toggle source
# File lib/pxeger.rb, line 10 def generate @reference = {} tree = process_grouping(@pattern.chars) tree = process_select(tree) process_others(tree) end
Private Instance Methods
choose(candinates)
click to toggle source
# File lib/pxeger.rb, line 243 def choose(candinates) candinates = candinates.dup candinates = candinates.chars if candinates.instance_of?(String) if candinates.instance_of?(Pxeger::Tree) && multi_backword_reference? ret = candinates.pick else ret = candinates.sample end if ((defined? ret) && ret.instance_of?(Pxeger::Tree)) ret = process_others(ret) end if (candinates.respond_to?(:num) && candinates.num) @reference[candinates.num] = ret end return ret || '' end
multi_backword_reference?()
click to toggle source
# File lib/pxeger.rb, line 19 def multi_backword_reference? return @is_multi_back_ref unless @is_multi_back_ref.nil? ref_indexes = @pattern.scan(/\\\d+/).map{|r| r.sub('\\','').to_i} @is_multi_back_ref = ref_indexes.any? {|i| i >= 2} end
process_grouping(pattern_array)
click to toggle source
# File lib/pxeger.rb, line 25 def process_grouping(pattern_array) tree = Tree.new stack = Tree.new([tree]) n = 1 while (char = pattern_array.shift) if (char == "\\") next_char = pattern_array.shift if (%w| ( ) |.include?(next_char)) stack[0].push(next_char) else stack[0].push(char, next_char) end elsif (char == '(') inner = Tree.new stack[0].push(inner) stack.unshift(inner) next_char = pattern_array.shift if (next_char == '?') next_char = pattern_array.shift if (next_char == ':') # nothing else raise "Invalid Group" end elsif (%w| ( ) |.include?(next_char)) pattern_array.unshift(next_char) else inner.num = n n += 1 inner.push(next_char) end elsif (char == ')') stack.shift else stack[0].push(char) end end return tree end
process_others(tree)
click to toggle source
# File lib/pxeger.rb, line 110 def process_others(tree) ret = '' candinates = Tree.new tree = tree.dup while (char = tree.shift) case char when '^' when '$' when '*' rand(10).times { ret << choose(candinates) } candinates = Tree.new when '+' (rand(10) + 1).times { ret << choose(candinates) } candinates = Tree.new when '{' brace = '' while (char = tree.shift) if (char == '}') break else brace << char end end if (char != '}') raise "missmatch brace: #{char}" end dd = brace.split(',') min = dd[0].to_i max = (dd.length == 1) ? min : (dd[1].to_i || 10) (rand(max - min + 1) + min).times { ret << choose(candinates) } candinates = Tree.new when '?' if rand(2) > 0 ret << choose(candinates) end candinates = Tree.new when '\\' ret << choose(candinates) escaped = tree.shift if (escaped.match(/^[1-9]$/)) candinates = [ @reference[escaped.to_i] || '' ] else if (%w(b B).include?(escaped)) raise "\\b and \\B is not supported" end candinates = CLASSES[escaped] end unless candinates candinates = Tree.new([escaped]) end when '[' ret << choose(candinates) sets = Tree.new negative = false while (char = tree.shift) if (char == '\\') next_char = tree.shift if (CLASSES[next_char]) sets = sets + CLASSES[next_char] else sets.push(next_char) end elsif (char == ']') break elsif (char == '^') before_char = sets.last if (!before_char) negative = true else sets.push(char) end elsif (char == '-') next_char = tree.shift if (next_char == ']') sets.push(char) char = next_char break end before_char = sets.last if (!before_char) sets.push(char) else ((before_char.ord + 1)...(next_char.ord)).each do |i| begin sets.push(i.chr("UTF-8")) rescue RangeError => e warn e if ENV["DEBUG"] end end end else sets.push(char) end end if (char != ']') raise "missmatch bracket: #{char}" end if (negative) neg = {} sets.each do |set| neg[set] = true end candinates = Tree.new ALL.each do |char| candinates.push(char) unless neg[char] end else candinates = sets end when '.' ret << choose(candinates) candinates = ALL else ret << choose(candinates) candinates = char end end return ret << choose(candinates) end
process_select(tree)
click to toggle source
# File lib/pxeger.rb, line 68 def process_select(tree) candinates = Tree.new([Tree.new]) while (char = tree.shift) if (char == '\\') next_char = tree.shift if (next_char == '|') candinates[0].push(next_char) else candinates[0].push(char, next_char) end elsif (char == '[') candinates[0].push(char) while (char = tree.shift) candinates[0].push(char) if (char == '\\') next_char = tree.shift candinates[0].push(next_char) elsif (char == ']') break end end elsif (char == '|') candinates.unshift(Tree.new) else candinates[0].push(char) end end candinates.each do |it| tree.push(it) len = it.length j = 0 while ( j < len ) process_select(it[j]) if it[j].instance_of?(Pxeger::Tree) j += 1 end end return Tree.new([tree]) end