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?, #pfx, #qmark, #quote, #root?, #wrap

Constructor Details

#initialize(engine, children) ⇒ CharClass

Returns a new instance of CharClass.



592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
# File 'lib/list_matcher.rb', line 592

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.



585
586
587
# File 'lib/list_matcher.rb', line 585

def num
  @num
end

#spaceObject

Returns the value of attribute space.



585
586
587
# File 'lib/list_matcher.rb', line 585

def space
  @space
end

#wordObject

Returns the value of attribute word.



585
586
587
# File 'lib/list_matcher.rb', line 585

def word
  @word
end

Instance Method Details

#atomic?Boolean

Returns:

  • (Boolean)


616
617
618
# File 'lib/list_matcher.rb', line 616

def atomic?
  true
end

#cc_quote(c) ⇒ Object



660
661
662
663
664
665
666
667
668
669
670
# File 'lib/list_matcher.rb', line 660

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



631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
# File 'lib/list_matcher.rb', line 631

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
    else
      mid = rs.map do |s, e|
        if s == e
          cc_quote s.chr
        elsif e == s + 1
          "#{ cc_quote s.chr }#{ cc_quote e.chr }"
        else
          "#{ cc_quote s.chr }-#{ cc_quote e.chr }"
        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



622
623
624
625
626
627
628
# File 'lib/list_matcher.rb', line 622

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

#flattenObject



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

def flatten; end

#ranges(chars) ⇒ Object



672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
# File 'lib/list_matcher.rb', line 672

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