2012-05-10 12 views
7

Rubyを使用して、ダウンロードしてダウンロードするファイルのURLを抽出しています。ファイル名にutf8文字(例:ASCII文字のURLエンコードはどうすればできますか?

www.domain.com/.../ÖÇÄÜ360ÓïÒôÖúÀí.txt 

上記のURLをダウンロードしようとすると失敗します。

www.domain.com/.../%C3%96%C3%87%C3%84%C3%9C360%C3%93%C3%AF%C3%92%C3%B4%C3%96%C3%BA%C3%80%C3%AD.txt 
しかし、私は URL Encoding Referenceに従うならば、それは動作します: URI::escapeを使用すると、動作しないというURIを生成

​​

私はまったく同じことをRubyで機能を検索してみましたエンコーディングが見つかりませんでした。上記のリンクにテーブルを実装する関数を書く前に、誰かがこれを行う既存のライブラリを知っているかどうか尋ねたいと思います。そして、私がこれをすることに決めたら、エンコードすべき文字の範囲は明らかです。すべてではありません。

私はRUBY_VERSION => "1.8.7"

+1

バイトC3 96は、UTF-8でエンコードされたÖです。同じ文字がASCIIで1バイトD6として表されます。だから、この問題にアプローチする一つの方法は、あなたのUTF-8文字をASCIIに変換してから、次にURI :: escapeに変換することです。しかし、それはASCII同等物を持っていないUnicode文字のためにあなたを助けません。 –

+0

['CGI.escape'](http://ruby-doc.org/stdlib-1.9.3/libdoc/cgi/rdoc/CGI.html#method-c-escape)を試しましたか? –

+0

@DavidGorsline:これは動作しません。私は '?'で終わる'360'と '.txt'を除くすべての文字に適用されます。上記の例は実際の例です。文字列'ÖÇÄÜ360ÓïÒôÖúÀí.txt 'でテストできるアイデアがあれば、それをどうすればいいか教えてください。ご協力いただきありがとうございます。 – Rami

答えて

15

ああ、文字エンコーディングの喜びとはJRuby 1.6.2を使用しています!

ここで起こっていることは次のとおりです。 Rubyは内部的に抽出した文字列を、ファイル名のutf-8エンコーディングであるバイト列として格納しています。 URI.escapeを呼び出すと、それらのバイトは%xy形式でエスケープされ、結果の文字列はASCII範囲のバイトのみで構成され、URLとして使用されます。

しかし、受信側のサーバーでは、別のエンコーディング(この場合はISO-8859-1)のように、これらのバイトを解釈しています(%xy形式からアンエスケープした後)持っている。

ここでは、エンコードのサポートが強化されているため、Ruby 1.9を使用したデモンストレーションです。

1.9.3-p194 :003 > f 
=> "ÖÇÄÜ360ÓïÒôÖúÀí.txt" 
1.9.3-p194 :004 > f.encoding 
=> #<Encoding:UTF-8> 
1.9.3-p194 :005 > URI.escape f 
=> "%C3%96%C3%87%C3%84%C3%9C360%C3%93%C3%AF%C3%92%C3%B4%C3%96%C3%BA%C3%80%C3%AD.txt" 
1.9.3-p194 :006 > g = f.encode 'iso-8859-1' 
=> "\xD6\xC7\xC4\xDC360\xD3\xEF\xD2\xF4\xD6\xFA\xC0\xED.txt" 
1.9.3-p194 :007 > g.encoding 
=> #<Encoding:ISO-8859-1> 
1.9.3-p194 :008 > URI.escape g 
=> "%D6%C7%C4%DC360%D3%EF%D2%F4%D6%FA%C0%ED.txt" 

この場合溶液、それを脱出する前に、ISO-8859-1などの文字列をエンコードすることです。あなたは(私は実際にはJRubyとその慣れていないよ、JRubyのは、Iconvにが含まれてと仮定している)Iconvにを使用することができRuby 1.9のでは、あなたが以前のバージョンでは、上記のようにこれを行う:

1.8.7 :001 > f 
=> "\303\226\303\207\303\204\303\234360\303\223\303\257\303\222\303\264\303\226\303\272\303\200\303\255.txt" 
1.8.7 :005 > g = Iconv.conv('iso-8859-1', 'utf-8', f) 
=> "\326\307\304\334360\323\357\322\364\326\372\300\355.txt" 
1.8.7 :006 > URI.escape f 
=> "%C3%96%C3%87%C3%84%C3%9C360%C3%93%C3%AF%C3%92%C3%B4%C3%96%C3%BA%C3%80%C3%AD.txt" 
1.8.7 :007 > URI.escape g 
=> "%D6%C7%C4%DC360%D3%EF%D2%F4%D6%FA%C0%ED.txt" 

注「一般的にあなたができること特定のエンコーディングを使用してサーバーに依存します。それは utf - 8を使用する必要がありますが、明らかにこの場合ではありません。

+0

恐ろしく、ありがとう! – Rami

+0

これはエンコード後にURI.escapeに必要な手がかりを得られなかったので非常に役に立ちました。 – KnuturO

関連する問題