2014/11/19追記
JavaScriptのencodeURIComponentにRubyのメソッドで近そうなのはWEBrick::HTTPUtils.escape_form
ほぼ同じなのですが、唯一の違いが半角スペースのエンコード。
encodeURIComponent だと %20 ですが、 WEBrick::HTTPUtils.escape_form だと + (プラス記号)になります。
WEBrick::HTTPUtils.escape_form してから + を %20 に置換(String#gsub("+", "%20"))してやればOK
JavaScriptのencodeURIComponentはRubyだとどう書く - 別館 子子子子子子(ねこのここねこ)
本編
URLエンコードなんだからURI.encode(もしくはURI.escape)とかだったよなーと思ったのだけど
このメソッドは obsolete です。
代わりに ERB::Util.#url_encode, CGI.escape, URI.encode_www_form_component, WEBrick::HTTPUtils.#escape_form, WEBrick::HTTPUtils.#escape などの使用を検討してください。 詳細は [ruby-core:29293] からのスレッドを参照してください。
…あらobsoleteだ。
メソッドの違いはどーなってんだか
いろいろメソッドがあるんだけど、当然ながら何かが違うから別メソッドなわけで。
何が違うんだろ、と思ったらさっきのMLにあった。
% ./ruby -rcgi -ruri -rwebrick/httputils -rerb -e ' table = [] (0..255).each {|c| s = [c].pack("C") e = [ ERB::Util.url_encode(s), CGI.escape(s), URI.encode_www_form_component(s), WEBrick::HTTPUtils.escape_form(s), WEBrick::HTTPUtils.escape(s), URI.escape(s), ] next if e.uniq.length == 1 p e table << e } '
結果がこちら。
ERB::Util.url_encode ┆ CGI.escape ┆ ┆ URI.encode_www_form_component ┆ ┆ ┆ WEBrick::HTTPUtils.escape_form ┆ ┆ ┆ ┆ WEBrick::HTTPUtils.escape ┆ ┆ ┆ ┆ ┆ URI.escape ┆ ┆ ┆ ┆ ┆ ┆
["%20", "+", "+", "+", "%20", "%20"] ["%21", "%21", "%21", "!", "!", "!"] ["%24", "%24", "%24", "%24", "$", "$"] ["%26", "%26", "%26", "%26", "&", "&"] ["%27", "%27", "%27", "'", "'", "'"] ["%28", "%28", "%28", "(", "(", "("] ["%29", "%29", "%29", ")", ")", ")"] ["%2A", "%2A", "*", "*", "*", "*"] ["%2B", "%2B", "%2B", "%2B", "+", "+"] ["%2C", "%2C", "%2C", "%2C", ",", ","] ["%2F", "%2F", "%2F", "%2F", "/", "/"] ["%3A", "%3A", "%3A", "%3A", ":", ":"] ["%3B", "%3B", "%3B", "%3B", ";", ";"] ["%3D", "%3D", "%3D", "%3D", "=", "="] ["%3F", "%3F", "%3F", "%3F", "?", "?"] ["%40", "%40", "%40", "%40", "@", "@"] ["%5B", "%5B", "%5B", "%5B", "%5B", "["] ["%5D", "%5D", "%5D", "%5D", "%5D", "]"] ["%7E", "%7E", "%7E", "~", "~", "~"] http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/29373
ちなみに全体図はこうなります。右端に文字そのものを追加しておきました。
["%20", "+", "+", "+", "%20", "%20", " "] ["%21", "%21", "%21", "!", "!", "!", "!"] ["%22", "%22", "%22", "%22", "%22", "%22", """] ["%23", "%23", "%23", "%23", "%23", "%23", "#"] ["%24", "%24", "%24", "%24", "$", "$", "$"] ["%25", "%25", "%25", "%25", "%25", "%25", "%"] ["%26", "%26", "%26", "%26", "&", "&", "&"] ["%27", "%27", "%27", "'", "'", "'", "'"] ["%28", "%28", "%28", "(", "(", "(", "("] ["%29", "%29", "%29", ")", ")", ")", ")"] ["%2A", "%2A", "*", "*", "*", "*", "*"] ["%2B", "%2B", "%2B", "%2B", "+", "+", "+"] ["%2C", "%2C", "%2C", "%2C", ",", ",", ","] ["-", "-", "-", "-", "-", "-", "-"] [".", ".", ".", ".", ".", ".", "."] ["%2F", "%2F", "%2F", "%2F", "/", "/", "/"] ["0", "0", "0", "0", "0", "0", "0"] ["1", "1", "1", "1", "1", "1", "1"] ["2", "2", "2", "2", "2", "2", "2"] ["3", "3", "3", "3", "3", "3", "3"] ["4", "4", "4", "4", "4", "4", "4"] ["5", "5", "5", "5", "5", "5", "5"] ["6", "6", "6", "6", "6", "6", "6"] ["7", "7", "7", "7", "7", "7", "7"] ["8", "8", "8", "8", "8", "8", "8"] ["9", "9", "9", "9", "9", "9", "9"] ["%3A", "%3A", "%3A", "%3A", ":", ":", ":"] ["%3B", "%3B", "%3B", "%3B", ";", ";", ";"] ["%3C", "%3C", "%3C", "%3C", "%3C", "%3C", "<"] ["%3D", "%3D", "%3D", "%3D", "=", "=", "="] ["%3E", "%3E", "%3E", "%3E", "%3E", "%3E", ">"] ["%3F", "%3F", "%3F", "%3F", "?", "?", "?"] ["%40", "%40", "%40", "%40", "@", "@", "@"] ["A", "A", "A", "A", "A", "A", "A"] ["B", "B", "B", "B", "B", "B", "B"] ["C", "C", "C", "C", "C", "C", "C"] ["D", "D", "D", "D", "D", "D", "D"] ["E", "E", "E", "E", "E", "E", "E"] ["F", "F", "F", "F", "F", "F", "F"] ["G", "G", "G", "G", "G", "G", "G"] ["H", "H", "H", "H", "H", "H", "H"] ["I", "I", "I", "I", "I", "I", "I"] ["J", "J", "J", "J", "J", "J", "J"] ["K", "K", "K", "K", "K", "K", "K"] ["L", "L", "L", "L", "L", "L", "L"] ["M", "M", "M", "M", "M", "M", "M"] ["N", "N", "N", "N", "N", "N", "N"] ["O", "O", "O", "O", "O", "O", "O"] ["P", "P", "P", "P", "P", "P", "P"] ["Q", "Q", "Q", "Q", "Q", "Q", "Q"] ["R", "R", "R", "R", "R", "R", "R"] ["S", "S", "S", "S", "S", "S", "S"] ["T", "T", "T", "T", "T", "T", "T"] ["U", "U", "U", "U", "U", "U", "U"] ["V", "V", "V", "V", "V", "V", "V"] ["W", "W", "W", "W", "W", "W", "W"] ["X", "X", "X", "X", "X", "X", "X"] ["Y", "Y", "Y", "Y", "Y", "Y", "Y"] ["Z", "Z", "Z", "Z", "Z", "Z", "Z"] ["%5B", "%5B", "%5B", "%5B", "%5B", "[", "["] ["%5C", "%5C", "%5C", "%5C", "%5C", "%5C", "\"] ["%5D", "%5D", "%5D", "%5D", "%5D", "]", "]"] ["%5E", "%5E", "%5E", "%5E", "%5E", "%5E", "^"] ["_", "_", "_", "_", "_", "_", "_"] ["%60", "%60", "%60", "%60", "%60", "%60", "`"] ["a", "a", "a", "a", "a", "a", "a"] ["b", "b", "b", "b", "b", "b", "b"] ["c", "c", "c", "c", "c", "c", "c"] ["d", "d", "d", "d", "d", "d", "d"] ["e", "e", "e", "e", "e", "e", "e"] ["f", "f", "f", "f", "f", "f", "f"] ["g", "g", "g", "g", "g", "g", "g"] ["h", "h", "h", "h", "h", "h", "h"] ["i", "i", "i", "i", "i", "i", "i"] ["j", "j", "j", "j", "j", "j", "j"] ["k", "k", "k", "k", "k", "k", "k"] ["l", "l", "l", "l", "l", "l", "l"] ["m", "m", "m", "m", "m", "m", "m"] ["n", "n", "n", "n", "n", "n", "n"] ["o", "o", "o", "o", "o", "o", "o"] ["p", "p", "p", "p", "p", "p", "p"] ["q", "q", "q", "q", "q", "q", "q"] ["r", "r", "r", "r", "r", "r", "r"] ["s", "s", "s", "s", "s", "s", "s"] ["t", "t", "t", "t", "t", "t", "t"] ["u", "u", "u", "u", "u", "u", "u"] ["v", "v", "v", "v", "v", "v", "v"] ["w", "w", "w", "w", "w", "w", "w"] ["x", "x", "x", "x", "x", "x", "x"] ["y", "y", "y", "y", "y", "y", "y"] ["z", "z", "z", "z", "z", "z", "z"] ["%7B", "%7B", "%7B", "%7B", "%7B", "%7B", "{"] ["%7C", "%7C", "%7C", "%7C", "%7C", "%7C", "|"] ["%7D", "%7D", "%7D", "%7D", "%7D", "%7D", "}"] ["%7E", "%7E", "%7E", "~", "~", "~", "~"]
CGI.escape_htmlは?
escapeと言うならば上記以外にCGI.escape_htmlもあるよな、と思った。でもちょっと調べたら、エンコードじゃなくて本当にエスケープだった。
与えられた文字列中の &"<> を実体参照に置換した文字列を新しく作成し返します。
singleton method CGI.escapeHTML (Ruby 1.9.3)
- unescapeHTML(string) -> String [added by cgi/util]
- unescape_html(string) -> String [added by cgi/util]
与えられた文字列中の実体参照のうち、& > < " と数値指定がされているもの (�ffff など) を元の文字列に置換します。
singleton method CGI.unescapeHTML (Ruby 1.9.3)
いちおう比較確認。encode.rbってのを書いてみた。
require 'uri' require 'cgi/util' (0..255).each do |c| s = [c].pack("C") e = [ URI.escape(s), URI.encode_www_form_component(s), CGI.escape(s), ] if e.uniq.length != 1 || CGI.escape_html(s) != s e_length = e.uniq.length e << CGI.escape_html(s) p e end end
実行。
URI.escape ┆ URI.encode_www_form_component ┆ ┆ CGI.escape ┆ ┆ ┆ CGI.escape_html ┆ ┆ ┆ ┆
$ ruby encode.rb ["%20", "+", "+", " "] ["!", "%21", "%21", "!"] ["%22", "%22", "%22", """] ["$", "%24", "%24", "$"] ["&", "%26", "%26", "&"] ["'", "%27", "%27", "'"] ["(", "%28", "%28", "("] [")", "%29", "%29", ")"] ["*", "*", "%2A", "*"] ["+", "%2B", "%2B", "+"] [",", "%2C", "%2C", ","] ["/", "%2F", "%2F", "/"] [":", "%3A", "%3A", ":"] [";", "%3B", "%3B", ";"] ["%3C", "%3C", "%3C", "<"] ["=", "%3D", "%3D", "="] ["%3E", "%3E", "%3E", ">"] ["?", "%3F", "%3F", "?"] ["@", "%40", "%40", "@"] ["[", "%5B", "%5B", "["] ["]", "%5D", "%5D", "]"] ["~", "%7E", "%7E", "~"]
あ、そういえば%20って半角スペースでしたね。「+」にエスケープされやすいから勘違いしてしまう。