[Ruby][Rails] CGI.escapeとURI.escape。
こんにちわ。ばたっちです。
WikiのようにURLに日本語のエスケープを使いたいと思いまして。。
CGI.escapeを使っていたのですが、他にも URI.escapeというのがありました。
URI - Rubyリファレンスマニュアル
http://www.ruby-lang.org/ja/man/html/URI.html
CGI - Rubyリファレンスマニュアル
http://www.ruby-lang.org/ja/man/html/cgi.html
若干、振る舞いが違うようで、たとえば CGI.escapeでは半角スペースが「+」に
変換されてしまうのですが、URI.escapeだと「%20」に変換してくれます。
ちなみに、Railsの link_toでも半角スペースは「%20」に変換されてますね。
ちょっと比較してみました。
URI.escapeでは、さらに第二引数でエスケープしない文字列を正規表現で指定できるようですね。
「aA1あ安 ^-_.!~*'();/?:@&=+$,[]"#%|\{}<>」という文字列を変換すると、以下のようになりました。
CGI.escape(str) => aA1%E3%81%82%E5%AE%89+%5E-_.%21%7E%2A%27%28%29%3B%2F%3F%3A%40%26%3D%2B%24%2C%5B%5D%22%23%25%7C%5C%7B%7D%3C%3E URI.escape(str) => aA1%E3%81%82%E5%AE%89%20%5E-_.!~*'();/?:@&=+$,[]%22%23%25%7C%5C%7B%7D%3C%3E URI.escape(str, /[^-_!~*'()a-zA-Z\d;\/?:@&=+$,\[\]]/n) (*1) => aA1%E3%81%82%E5%AE%89%20%5E-_%2E!~*'();/?:@&=+$,[]%22%23%25%7C%5C%7B%7D%3C%3E url_for (Rails) => aA1%E3%81%82%E5%AE%89%20%5E-_.!~*'();%2F%3F:@&=+$,%5B%5D%22%23%25%7C%7B%7D%3C%3E
3つ目のエスケープパターンは、デフォルトのURI::UNSAFEから「.」を除去した場合です。
さらに、unescapeで逆変換した場合の結果。
(cescは CGI.escape、uescは URI.escape、mescは URI.escape(str, pattern)でそれぞれエスケープした文字列)
CGI.unescape(cesc) => aA1あ安 ^-_.!~*'();/?:@&=+$,[]"#%|\{}<> CGI.unescape(uesc) => aA1あ安 ^-_.!~*'();/?:@&= $,[]"#%|\{}<> CGI.unescape(mesc) => aA1あ安 ^-_.!~*'();/?:@&= $,[]"#%|\{}<> URI.unescape(cesc) => aA1あ安+^-_.!~*'();/?:@&=+$,[]"#%|\{}<> URI.unescape(uesc) => aA1あ安 ^-_.!~*'();/?:@&=+$,[]"#%|\{}<> URI.unescape(mesc) => aA1あ安 ^-_.!~*'();/?:@&=+$,[]"#%|\{}<>
URI.escapeで変換したものは、URI.unescapeで変換しないと「+」が半角スペースに変換されてしまいます。
Railsの URLに「+」があった場合は半角スペースには直してくれないので、URI.unescapeに近い動きのようですね。