longest match

最長最左マッチ。

require 'strscan'

def longest_match(scanner, res)
  sz = 0
  regexp = nil
  
  res.each {|re|
    x = scanner.match?(re)
    if (x ||= 0) > sz
      regexp = re
      sz = x
    end
  }
  
   yield(regexp, regexp ? scanner.scan(regexp) : nil)
end

longest_match(StringScanner.new("iffff"), [/if/, /[a-z]+/]) {|re,tkn| tkn }   => "iffff"
longest_match(StringScanner.new("if"), [/if/, /[a-z]+/]) {|re,tkn| tkn }      => "if"
longest_match(StringScanner.new("12345"), [/if/, /[a-z]+/]) {|re,tkn| tkn }   => nil

どうしようもない系だけど、Rubyの組み込み正規表現を活用するとこんな感じだろうか。遅かったら、Cで書き直す。つーか覚悟を決めてflex使う。

※バグってたので修正