# 面接用 require 'cgi' require 'uri' require 'strscan' class TextStyle def initialize(rules = nil) @rules = Array.new if (rules) add(rules) end end def clear @rules.clear end def add(*args) if ( args[0].instance_of?(Hash) ) add_hash(args[0]) elsif ( args[0].instance_of?(Array) ) add_hash_array(args[0]) elsif ( args.size > 0 ) add_param(args[0], args[1], args.size > 1 ? args[2] : nil) else raise ArgumentError end end def add_hash_array(rules) if (rules) rules.each do |rule| add_hash(rule) end end end def add_hash(param) add(param[:re], param[:filter], param[:priority]) end def add_param(re, filter, priority = nil) if (priority.nil?) priority = @rules.empty? ? 0 : @rules[-1][:priority] + 1 end @rules << { :priority => priority, :re => re, :filter => filter } end def eval(text) rules = @rules.sort do |a, b| a[:priority] <=> b[:priority] end return eval_rule(text, rules, 0) end protected def eval_rule(text, rules, i) output = String.new if (i >= rules.size || text.nil?) return output end scanner = StringScanner.new(text) post_match = nil until scanner.eos? token = scanner.scan_until(rules[i][:re]) if (token) output << eval_rule(scanner.pre_match, rules, i + 1) + rules[i][:filter].call(scanner.matched) scanner.string = scanner.post_match else output << eval_rule(scanner.string, rules, i + 1) break end end return output end end rules = [{ :priority => 1, :re => /s?https?:\/\/[-_\da-zA-Z.!~*'\(\);\/?:@&=+$,%\#]+/, :filter => Proc.new do |s| sprintf('%s', URI.escape(s), CGI.escapeHTML(s)) end }, { :priority => 2, :re => /@[a-zA-Z_]+/, :filter => Proc.new do |s| sprintf('%s', URI.escape(s), CGI.escapeHTML(s)) end }, { :priority => 3, :re => /#[a-zA-Z_]+/, :filter => Proc.new do |s| sprintf('%s', URI.escape(s), CGI.escapeHTML(s)) end }, { :priority => 4, :re => /.+/, :filter => Proc.new do |s| CGI.escapeHTML(s) end } ] s = TextStyle.new(rules) puts s.eval("@kusobot きた~ http://www.example.net/@kusobot#kusobot o-('-'o)#kusobot hoge") # @kusobot <s>きた~ http://www.example.net/@kusobot#kusobot o-('-'o)#kusobot hoge rules[0][:priority] = 2 rules[1][:priority] = 1 s.clear s.add(rules) puts s.eval("@kusobot きた~ http://www.example.net/@kusobot#kusobot o-('-'o)#kusobot hoge") # @kusobot <s>きた~ http://www.example.net/@kusobot#kusobot o-('-'o)#kusobot hoge s.clear s.add(rules[1]) s.add(rules[2]) s.add(rules[3]) puts s.eval("@kusobot きた~ http://www.example.net/@kusobot#kusobot o-('-'o)#kusobot hoge") # @kusobot <s>きた~ http://www.example.net/@kusobot#kusobot o-('-'o)#kusobot hoge