ruby - Regex put in via formtastic gets altered (maybe by the controller) before it's put into Mongoid -


i have form put in hashes regular expression values. problem gets messed when travelling view, through controller , mongodb mongoid. how preserve regex'es?

input examples:

{:regex1 => "^something \(#\d*\)$"} {:regex2 => "\a[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z"} 

my formtastic view form looks this:

= semantic_form_for resource, :html => {:class => "form-vertical"} |r|   = r.inputs     = r.input :value, :as => :text   = r.actions     = r.action :submit 

my controller create action takes in params , handles this:

class emailtypescontroller < inheritedresources::base    def create     puts params[:email_type][:value]          # =>  {:regex1 => "^something \(#\d*\)$"} ,                                               #     {:regex2 => "\a[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z"}     puts params[:email_type][:value].inspect  # =>  "{:regex1 => \"^something \\(#\\d*\\)$\"}" ,                                               #     "{:regex2 => \"\\a[\\w+\\-.]+@[a-z\\d\\-.]+\\.[a-z]+\\z\"}"      params[:email_type][:value] = convert_to_hash(params[:email_type][:value])      puts params[:email_type][:value]          # =>  {"regex1"=>"^something (#d*)$"} ,                                               #     {"regex2"=>"a[w+-.]+@[a-zd-.]+.[a-z]+z"}     create! |success, failure|        success.html {         redirect_to resource       }        failure.html {         render :action => :new       }     end       end    def convert_to_hash(string)     if string.match(/(.*?)=>(.*)\n*/)       string = eval(string)     else       string = string_to_hash(string)     end   end    def string_to_hash(string)     values = string.split("\r\n")     output = {}     values.each |v|       val = v.split("=")       output[val[0].to_sym] = val[1]     end     output   end end 

firing console , inspecting values put in through mongoid:

loading development environment (rails 3.2.12) 1.9.3p385 :001 > emailtype.all.each |email_type| 1.9.3p385 :002 >     puts email_type.value 1.9.3p385 :003?>   end {"regex1"=>"^something (#d*)$"} {"regex2"=>"a[w+-.]+@[a-zd-.]+.[a-z]+z"}  => true  1.9.3p385 :004 >  

the problem lies in ruby's evaluation of strings, ignores useless escapes:

puts "^something \(#\d*\)$".inspect =>"^something (#d*)$" 

that eval ignores backslash. note typically in ruby regexes aren't created using strings through own regex literal, that

/^something \(#\d*\)$/.inspect =>"/^something \\(#\\d*\\)$/" 

notice double backslash instead of single. means eval has receive 2 backslashes instead of 1 in string, has eval'd single backslash character.

a quick , easy way run sub ob string before convert_to_hash call:

# little confusing due escapes, single backslashes replaced double. # second parameter confusing, appears string#sub requires few # escapes due backslashes being used backreference. # i.e. \n replaced nth regex group, replace string # "\n" yet escape backslash required, "\\n" replaced "\n". # therefore input of 8 blackslashes eval'd string of 4 backslashes, # sub interprets 2 backslashes. params[:email_type][:value].gsub!('\\', '\\\\\\\\') 

this shouldn't problem unless using backslashes in hash keys @ point, in case more advanced matching needed extract regex's , perform substitution on them.


Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -