class Fluent::GlobMatchPattern

Public Class Methods

new(pat) click to toggle source
# File lib/fluent/match.rb, line 35
def initialize(pat)
  if pat.start_with?('/')
    if pat.end_with?('/')
      @regex = Regexp.new("\\A"+pat[1..-2]+"\\Z")
      return
    else
      raise Fluent::ConfigError,  "invalid match - regex"
    end
  end

  stack = []
  regex = ['']
  escape = false
  dot = false

  i = 0
  while i < pat.length
    c = pat[i,1]

    if escape
      regex.last << Regexp.escape(c)
      escape = false
      i += 1
      next

    elsif pat[i,2] == "**"
      # recursive any
      if dot
        regex.last << "(?![^\\.])"
        dot = false
      end
      if pat[i+2,1] == "."
        regex.last << "(?:.*\\.|\\A)"
        i += 3
      else
        regex.last << ".*"
        i += 2
      end
      next

    elsif dot
      regex.last << "\\."
      dot = false
    end

    if c == "\\"
      escape = true

    elsif c == "."
      dot = true

    elsif c == "*"
      # any
      regex.last << "[^\\.]*"

      # TODO
      #elsif c == "["
      #  # character class
      #  chars = ''
      #  while i < pat.length
      #    c = pat[i,1]
      #    if c == "]"
      #      break
      #    else
      #      chars << c
      #    end
      #    i += 1
      #  end
      #  regex.last << '['+Regexp.escape(chars).gsub("\\-",'-')+']'

    elsif c == "{"
      # or
      stack.push []
      regex.push ''

    elsif c == "}" && !stack.empty?
      stack.last << regex.pop
      regex.last << Regexp.union(*stack.pop.map {|r| Regexp.new(r) }).to_s

    elsif c == "," && !stack.empty?
      stack.last << regex.pop
      regex.push ''

    elsif /[a-zA-Z0-9_]/.match?(c)
      regex.last << c

    else
      regex.last << "\\#{c}"
    end

    i += 1
  end

  until stack.empty?
    stack.last << regex.pop
    regex.last << Regexp.union(*stack.pop).to_s
  end

  @regex = Regexp.new("\\A"+regex.last+"\\Z")
end

Public Instance Methods

match(str) click to toggle source
# File lib/fluent/match.rb, line 136
def match(str)
  @regex.match?(str)
end