Class: List::Matcher::CharClass

Inherits:
Node
  • Object
show all
Defined in:
lib/list_matcher.rb

Constant Summary collapse

WORD_CHARS =
(1..255).map(&:chr).select{ |c| /\w/ === c }.freeze
CI_WORD_CHARS =
WORD_CHARS.map(&:downcase).uniq.freeze
NUM_CHARS =
CI_WORD_CHARS.select{ |c| /\d/ === c }.freeze
SPACE_CHARS =
(1..255).map(&:chr).select{ |c| /\s/ === c }.freeze

Instance Attribute Summary collapse

Attributes inherited from Node

#engine, #optional, #root, #symbols

Instance Method Summary collapse

Methods inherited from Node

#bound, #children, #finalize, #optional?, #optionalize, #pfx, #qmark, #quote, #root?, #wrap

Constructor Details

#initialize(engine, children) ⇒ CharClass

Returns a new instance of CharClass.



645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
# File 'lib/list_matcher.rb', line 645

def initialize(engine, children)
  super(engine, nil)
  if engine.case_insensitive
    if ( CI_WORD_CHARS - children ).empty?
      self.word = true
      self.num = false
      children -= CI_WORD_CHARS
    end
  elsif ( WORD_CHARS - children ).empty?
    self.word = true
    self.num = false
    children -= WORD_CHARS
  end
  if num.nil? && ( NUM_CHARS - children ).empty?
    self.num = true
    children -= NUM_CHARS
  end
  if ( SPACE_CHARS - children ).empty?
    self.space = true
    children -= SPACE_CHARS
  end
  @children = children
end

Instance Attribute Details

#numObject

Returns the value of attribute num.



638
639
640
# File 'lib/list_matcher.rb', line 638

def num
  @num
end

#spaceObject

Returns the value of attribute space.



638
639
640
# File 'lib/list_matcher.rb', line 638

def space
  @space
end

#wordObject

Returns the value of attribute word.



638
639
640
# File 'lib/list_matcher.rb', line 638

def word
  @word
end

Instance Method Details

#atomic?Boolean

Returns:

  • (Boolean)


669
670
671
# File 'lib/list_matcher.rb', line 669

def atomic?
  true
end

#cc_quote(c) ⇒ Object



713
714
715
716
717
718
719
720
721
722
723
# File 'lib/list_matcher.rb', line 713

def cc_quote(c)
  return Regexp.quote(c) if c =~ /\s/
  case c
  when '[' then '\['
  when ']' then '\]'
  when '\\' then '\\\\'
  when '-' then '\-'
  when '^' then '\^'
  else c
  end
end

#char_class(chars) ⇒ Object

takes a list of characters and returns a character class expression matching it



684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
# File 'lib/list_matcher.rb', line 684

def char_class(chars)
  mid = if chars.empty?
    ''
  else
    rs = ranges(chars)
    if rs.size == 1 && rs[0][0] == rs[0][1]
      cc_quote rs[0][0].chr(engine.encoding)
    else
      mid = rs.map do |s, e|
        if s == e
          cc_quote s.chr(engine.encoding)
        elsif e == s + 1
          "#{ cc_quote s.chr(engine.encoding) }#{ cc_quote e.chr(engine.encoding) }"
        else
          "#{ cc_quote s.chr(engine.encoding) }-#{ cc_quote e.chr(engine.encoding) }"
        end
      end.join
    end
  end
  mid += '\w' if word
  mid += '\d' if num
  mid += '\s' if space
  if mid.length == 1 || mid =~ /\A\\\w\z/
    mid
  else
    "[#{mid}]"
  end
end

#convertObject



675
676
677
678
679
680
681
# File 'lib/list_matcher.rb', line 675

def convert
  rx = char_class children
  if optional?
    rx += qmark
  end
  rx
end

#flattenObject



673
# File 'lib/list_matcher.rb', line 673

def flatten; end

#ranges(chars) ⇒ Object



725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
# File 'lib/list_matcher.rb', line 725

def ranges(chars)
  chars = chars.map(&:ord).sort
  rs = []
  c  = chars.shift
  r  = [ c, c ]
  while chars.size > 0
    c = chars.shift
    if c == r[1] + 1
      r[1] = c
    else
      rs << r
      r = [ c, c ]
    end
  end
  rs << r
end