class List::Matcher::Sequence
Public Class Methods
new(engine, *constituents)
click to toggle source
Calls superclass method
List::Matcher::Node::new
# File lib/list_matcher.rb, line 563 def initialize(engine, *constituents) super(engine, nil) @children = constituents end
Public Instance Methods
atomy?(s)
click to toggle source
infer atomic patterns
# File lib/list_matcher.rb, line 621 def atomy?(s) s.size == 1 || /\A(?>\\\w|\[(?>[^\[\]\\]|\\.)++\])\z/ === s end
condense(elements)
click to toggle source
iterated repeat condensation
# File lib/list_matcher.rb, line 626 def condense(elements) while elements.size > 1 condensate = condense_repeats elements break if condensate == elements elements = condensate end elements.join end
condense_repeats(elements)
click to toggle source
looks for repeating subsequences, as in ababababab, and condenses them to (?>ab){5} condensation is only done when it results in a more compact regex
# File lib/list_matcher.rb, line 586 def condense_repeats(elements) (1..(elements.size/2)).each do |l| # length of subsequence considered (0...l).each do |o| # offset from the start of the sequence dup_count = [] (1...(elements.size - o)/l).each do |s| # the sub-sequence number s2 = s * l + o s1 = s2 - l seq1 = elements[s1...s1 + l] seq2 = elements[s2...s2 + l] if seq1 == seq2 s0 = s - 1 counts = dup_count[s] = dup_count[s0] || [ 1, seq1.join, s1, nil ] counts[0] += 1 counts[3] = s2 + l dup_count[s0] = nil end end dup_count.compact! if dup_count.any? copy = elements.dup dup_count.reverse.each do |repeats, seq, start, finish| a = atomy? seq sl = seq.length if ( a ? 0 : engine.wrap_size ) + 2 + repeats.to_s.length + sl < sl * repeats copy[start...finish] = ( a ? seq : wrap(seq) ) + "{#{repeats}}" return copy; end end end end end elements end
convert()
click to toggle source
# File lib/list_matcher.rb, line 568 def convert rx = condense children.map(&:convert) finalize rx end
flatten()
click to toggle source
Calls superclass method
List::Matcher::Node#flatten
# File lib/list_matcher.rb, line 573 def flatten super (0...children.size).to_a.reverse.each do |i| c = children[i] if c.is_a?(Sequence) && !c.optional? children.delete_at i children.insert i, *c.children end end end