149 votes

Comment coder une chaîne de caractères en Ruby ?

Comment puis-je URI::encode une chaîne comme :

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

pour l'obtenir dans un format comme :

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

conformément à la RFC 1738 ?

Voici ce que j'ai essayé :

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>'

Aussi :

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>'

J'ai cherché partout sur Internet et je n'ai pas trouvé de moyen de le faire, bien que je sois presque certain de l'avoir fait l'autre jour sans le moindre problème.

1 votes

Peut-être utile si vous utilisez Ruby 1.9 : yehudakatz.com/2010/05/05/…

189voto

kain Points 3282
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 CGI.escape str

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

2 votes

force_encoding('binary') pourrait être un choix plus auto-documenté.

65 votes

Ils ont déprécié cette méthode, utilisez * CGI.escape * à la place. -> http://www.ruby-forum.com/topic/207489#903709 . Vous devriez également être en mesure d'utiliser URI.www_form_encode * URI.www_form_encode_component *, mais je ne les ai jamais utilisés

2 votes

Pas besoin de require 'open-uri' ici. Voulez-vous dire require 'uri' ?

102voto

Jenner LaFave Points 77

Aujourd'hui, vous devriez utiliser ERB::Util.url_encode o CGI.escape . La principale différence entre eux réside dans leur gestion des espaces :

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

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

CGI.escape suit le Spécifications des formulaires CGI/HTML et vous donne un application/x-www-form-urlencoded qui exige que les espaces soient échappés en + alors que ERB::Util.url_encode suit RFC 3986 ce qui exige qu'ils soient codés en tant que %20 .

Voir "https://stackoverflow.com/questions/2824126/whats-the-difference-between-uri-escape-and-cgi-escape/13059657#13059657" pour plus de détails.

72voto

Jared Beck Points 4975
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"

Tiré du commentaire de @J-Rou

11voto

Shein Alexey Points 447

Vous pouvez utiliser Addressable::URI un joyau pour cela :

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" 

Il utilise un format plus moderne que CGI.escape par exemple, il code correctement l'espace en tant que %20 et non comme + Pour en savoir plus, consultez la rubrique " Le type application/x-www-form-urlencoded "sur 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"

0 votes

On peut aussi faire comme ça : CGI.escape('Hello, this is me').gsub("+", "%20") => Hello%2C%20this%20is%20me" si vous ne voulez pas utiliser de gemmes

10voto

kangkyu Points 1067

À l'origine, j'essayais d'échapper aux caractères spéciaux dans un nom de fichier uniquement, et non dans le chemin, à partir d'une chaîne d'URL complète.

ERB::Util.url_encode n'a pas fonctionné pour mon usage :

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

Basé sur deux réponses dans " Pourquoi URI.escape() est-il marqué comme obsolète et où se trouve cette constante REGEXP::UNSAFE ? ", cela ressemble à URI::RFC2396_Parser#escape est préférable à l'utilisation de URI::Escape#escape . Cependant, ils se comportent tous deux de la même manière pour moi :

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"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X