tags:

views:

141

answers:

2

Hi,

I need to parse a string like this: a[metadata][][name]=dont|do|this&a[name]=Hello World&a[metadata][][value]=i|really|mean it

CGI::parse gives me this:

{"a[name]"=>["Hello World"], "a[metadata][][name]"=>["dont|do|this"], "a[metadata][][value]"=>["i|really|mean it"]}

I would like something like what PHP does with parse_str, which when given the same string does this:

Array
(
    [a] => Array
        (
            [metadata] => Array
                (
                    [0] => Array
                        (
                            [name] => dont|do|this
                        )

                    [1] => Array
                        (
                            [value] => i|really|mean it
                        )

                )

            [name] => Hello World
        ))

Any help would be awesome.

Thanks!

A: 

do you want to get output of hash like this?

hash = {:a => {:metadata => [{:name => "dont|do|this"}, {:value => "i|really|mean it"}], :name => "Hello World"}
Esse
Yes, more or less exactly what I would like to get out.
A: 

Haven't really gotten any responses, and still haven't found an equivalent function, so, for my purposes this works, based off something I found that _why had posted on the now missing redhanded.hobix.com or what not.

hash1 = {}
hash2 = {}
array1 = []
array2 = []
resulthash = {}
count = 0
count2 = 0
keynum2 = 0
main = 'base'
h3main = 'base'
st.scan(/([\w]+)(\[|=)(.*?)(?=(&[\w]+\[|&[\w]+=|$))/) {
  var = $1 << $2 << $3  
  case var
  when /^([\w]+)\[(.*?)\]\[(\d+)\]\[(.*?)\]=(.*?)$/ then
    count2 += 1
     h3main = $2
     keynum2 = $2 << count2.to_s
     i = $3.to_i
     array1[i] = {} if array1[i].class != Hash
     array1[i].update({$4 => $5})
     hash2.update(keynum2 => array1)
  when /^([\w]+)\[(.*?)\]\[\]\[(.*?)\]=(.*?)$/ then
     count2 += 1
     h3main = $2
     keynum2 = $2 << count2.to_s
     i = count2
     array2[i] = {} if array2[i].class != Hash
     array2[i].update({$4 => $5})
     hash2.update(keynum2 => array2)
  when /^([\w]+)\[(.*?)\]=(.*?)$/ then 
     main = $1
     count += 1
     keynum = $1 << count.to_s
     hash1.update(keynum => {$2 => $3})
  when /^(a)=(.*?)$/ then 
    resulthash.update($1 => $2)
  end
}
hashx = {}
hash1.each_pair {|k,v| hashx.update(main => v) }
resulthash[main] = hashx
if not hash2.empty? then
  if not resulthash[h3main].class == Hash then
    resulthash[main][h3main] = {}
  end
  hash2.each_pair{ |k,v| 
    if v.class == Array then
      resulthash[main][h3main] = v
    else
      resulthash[main][h3main].update(v)
    end
  }
end

The above kinda works, note, there's know real way for me to tell how to group [] items, so they are in an array as individual items. It's best to set the index, like a[somegroup][0][value] etc.

This was copy pasted and generalized so caveat usor.