« [MySQL][Rails] MySQL+Sennaの全文検索でスコア順にソートする。 | メイン | [Trac] チケットを階層化したい。 »

[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:@&amp;=+$,%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に近い動きのようですね。

トラックバック

このエントリーのトラックバックURL:
http://pw.tech-arts.co.jp/cgi-bin/tamt32/mt-tb.cgi/68

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)