1

私が持っていると言う

str = "a=2&b=3.05&c=testing"

走る

require 'cgi'
out = {}
CGI::parse(str).each { |k,v| out[k] = v[0] }

私が出力するときa、2は、string私がそれをしたいときは、Int

out['a'] // "2" (instead of int 2)
out['b'] // "3.05" (instead of float 3.05)

クエリ文字列から型を修正する方法はありますか?

アップデート:

数値をテストするためにこのメソッドを追加しました

def is_a_number?(s)
  s.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true 
end

解析中

CGI::parse(url).each do |k,v|
    val = v[0]
    if is_a_number? val 
        val = val.include?('.') ? val.to_f : val.to_i
    end 
    out[k] = val 
end 

基本的な例で動作するようです。これについて何か危険なことはありますか?

4

4 に答える 4

3

簡単な答えはノーです。正しいタイプを取り出す方法はありません。正規表現の一致に基づいて推測しようとする独自のパーサーを作成できます。これを処理する一般的な方法は、各パラメーターの予想されるタイプに基づいて手動で解析することです。のようなメソッドを呼び出して、必要なタイプto_ito_f変換できます。

于 2012-12-05T22:30:58.070 に答える
2

編集済み:これは機能します

require 'cgi'

str = "a=2&b=3.05&c=testing"
out = {}

def typecasted(str)
  [str.to_i, str.to_f, str].find { |cast| cast.to_s == str }
end

CGI::parse(str).each do |key, val|
  out[key] = typecasted val.first
end

p out
# => {"a"=>2, "b"=>3.05, "c"=>"testing"}
于 2012-12-06T01:26:42.050 に答える
1

このように解析すれば、問題はないはずです。

out = {}
CGI::parse(str).each do |k, v|
  v, v = (v = v.first), (v if v[/[a-zA-Z]/]) || [v.to_i, v.to_f].max
  out.merge!(Hash[k, v])
end    

AJcodezの技術と組み合わせると、これは

out = {}
CGI::parse(str).each do |k, v|
  v, out[k] = (v = v.first), [v.to_i, v.to_f, v].find { |c| c.to_s == v }
end 

またはワンライナーとして

Hash[*CGI::parse(str).map {|k, v| v = v.first; [k, [v.to_i, v.to_f, v].find { |c| c.to_s == v }]}.flatten]

与える

{"a"=>2, "b"=>3.05, "c"=>"testing"}
于 2012-12-05T22:58:37.490 に答える
-1

私はあなたが持っているその入力文字列で方法を考えることはできませんが、あなたがそれをに変更することができれば

str = "a=2&b=3.05&c='testing'"

(一重引用符に注意してください)、各値でeval関数を使用して、rubyに型を推測させることができます。

于 2012-12-05T22:34:50.270 に答える