web-dev-qa-db-ja.com

Ruby urlエンコード文字列

次のような文字列をURI :: encodeする方法

\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a

次のような形式で取得するには:

%124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A

(RFC 1738による)

私が試したものは次のとおりです。

irb(main):123:0> URI::encode "\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a"
ArgumentError: invalid byte sequence in UTF-8
    from /usr/local/lib/Ruby/1.9.1/uri/common.rb:219:in `gsub'
    from /usr/local/lib/Ruby/1.9.1/uri/common.rb:219:in `escape'
    from /usr/local/lib/Ruby/1.9.1/uri/common.rb:505:in `escape'
    from (irb):123
    from /usr/local/bin/irb:12:in `<main>'

また、

irb(main):126:0> CGI::escape "\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a"
ArgumentError: invalid byte sequence in UTF-8
    from /usr/local/lib/Ruby/1.9.1/cgi/util.rb:7:in `gsub'
    from /usr/local/lib/Ruby/1.9.1/cgi/util.rb:7:in `escape'
    from (irb):126
    from /usr/local/bin/irb:12:in `<main>'

私はインターネットのすべてを調べましたが、これを行う方法を見つけていません(または見逃している可能性が高い)。

ありがとう!

123
HRÓÐÓLFR
require 'uri'
str = "\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a".force_encoding('ASCII-8BIT')
puts URI::encode(str)

更新:以下のコメントを参照してください Ruby url encoding string

165
kain
str = "\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a"
require 'cgi'
CGI.escape(str)
# => "%124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A"

@ J-Rouのコメントから引用

68
Jared Beck

最近では、ERB::Util.url_encodeまたはCGI.escapeを使用する必要があります。それらの主な違いは、スペースの処理です。

>> ERB::Util.url_encode("foo/bar? baz&")
=> "foo%2Fbar%3F%20baz%26"

>> CGI.escape("foo/bar? baz&")
=> "foo%2Fbar%3F+baz%26"

CGI.escapeCGI/HTMLフォーム仕様に従いapplication/x-www-form-urlencoded文字列を提供します。これは、スペースを+にエスケープする必要がありますが、ERB::Util.url_encodeRFC 3986%20としてエンコードする必要があります。

詳細については、 この回答 を参照してください。

66
Jenner La Fave

そのためにAddressable::URI gemを使用できます。

require 'addressable/uri'   
string = '\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a'
Addressable::URI.encode_component(string, Addressable::URI::CharacterClasses::QUERY)
# "%5Cx12%5Cx34%5Cx56%5Cx78%5Cx9a%5Cxbc%5Cxde%5Cxf1%5Cx23%5Cx45%5Cx67%5Cx89%5Cxab%5Cxcd%5Cxef%5Cx12%5Cx34%5Cx56%5Cx78%5Cx9a" 

CGI.escapeよりも最新の形式を使用します。たとえば、スペースを%20記号としてではなく、+として適切にエンコードします。詳細については、 wikipediaの記事 を参照してください。

2.1.2 :008 > CGI.escape('Hello, this is me')
 => "Hello%2C+this+is+me" 
2.1.2 :009 > Addressable::URI.encode_component('Hello, this is me', Addressable::URI::CharacterClasses::QUERY)
 => "Hello,%20this%20is%20me" 
8
Alexey Shein

コードで使用するuriエンコーディングをクリーンにするためのgemを作成しました。バイナリエンコーディングを処理します(上記のコードにサンプルの一部を追加しました)。

gem install uri-handlerを実行します。

require 'uri-handler'

str = "\x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a".to_uri
# => "%124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A"

Uri変換機能をStringクラスに追加します。使用したいオプションのエンコード文字列を引数に渡すこともできます(デフォルトでは、ストレートUTF-8エンコードが失敗した場合、エンコード「バイナリ」に設定されます)。

5
foomip

元々、完全なURL文字列から(パス上ではなく)ファイル名のみの特殊文字をエスケープしようとしていました。 ERB::Util.url_encodeは私の使用では機能しませんでした。

helper.send(:url_encode, "http://example.com/?a=\11\15")
# => "http%3A%2F%2Fexample.com%2F%3Fa%3D%09%0D"

異なるSO question の2つの回答に基づくと、URI::RFC2396_Parser#escapeURI::Escape#escapeを使用するよりも優れているようです。ただし、どちらも同じ動作をします。

URI.escape("http://example.com/?a=\11\15")
# => "http://example.com/?a=%09%0D"
URI::Parser.new.escape("http://example.com/?a=\11\15")
# => "http://example.com/?a=%09%0D"
2
kangkyu

コード:

str = "http://localhost/with spaces and spaces"
encoded = URI::encode(str)
puts encoded

結果:

http://localhost/with%20spaces%20and%20spaces
0
Thiago Falcao

手動でURLを別の部分に分割することを考えずに完全なURLを「エンコード」したい場合は、URI.encodeを使用したときと同じように機能することがわかりました。

URI.parse(my_url).to_s
0