Як витягти параметри URL-адреси з URL-адреси за допомогою Ruby або Rails?


137

У мене є такі URL-адреси, як

http://www.example.com/something?param1=value1&param2=value2&param3=value3

і я хотів би витягти параметри з цих URL-адрес і отримати їх у хеші. Очевидно, я міг використовувати регулярні вирази, але мені було просто цікаво, чи існують простіші способи зробити це з Ruby чи Rails. У модулі Ruby я нічого не знайшов, URIале, можливо, я щось пропустив.

Насправді мені потрібен метод, який би це зробив:

extract_parameters_from_url("http://www.example.com/something?param1=value1&param2=value2&param3=value3")
#=> {:param1 => 'value1', :param2 => 'value2', :param3 => 'value3'}

Чи мали б ви поради?


1
Hash[*string.split('&').collect{|i|i.split('=')}.flatten] Це теж працювало б, але це, мабуть, найгірший варіант для цього випадку. Але все ж вам може здатися цікавим цей фрагмент. (Публікую як коментар, оскільки я не вважаю це відповіддю :-))
Войто

Відповіді:


162

Я думаю, ви хочете перетворити будь-який заданий рядок URL у HASH?

Ви можете спробувати http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html#M000075

require 'cgi'

CGI::parse('param1=value1&param2=value2&param3=value3')

повертає

{"param1"=>["value1"], "param2"=>["value2"], "param3"=>["value3"]}

1
Добре, це я пропустив! Це ідеально під час використання з URI.parse: CGI.parse (URI.parse (" example.com/… ) повертає потрібний хеш. Дякую за допомогу.
Flackou

91
Для наочності @Flackou хоче цього: CGI.parse(URI.parse(url).query)
glenn jackman

Я цього не перевіряв, але перший перелічений ключ, що містить повну URL-адресу, здається дійсно неправильним.
Леві

2
Я фактично повинен був скористатися цим: CGI::parse(URI::parse(url).query)
portforwardpodcast

151

Я виявив, що мені потрібно те саме для нещодавнього проекту. Спираючись на рішення Леві, ось більш чистий і швидкий метод:

Rack::Utils.parse_nested_query 'param1=value1&param2=value2&param3=value3'
# => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"}

Набагато легший, ніж знущатися із запиту на стійки
Гарет

2
Гарна знахідка. Якщо у вас є прості параметри (не вкладені) та чутливі до продуктивності, Rack :: Utils.parse_query може представляти інтерес. Код варто прочитати: github.com/rack/rack/blob/master/lib/rack/utils.rb
Levi

Дякую, це дуже корисно :)
Blue Smith

Це добре працює , але не працює для прапорців з тим же ім'ям param1=value1&param1=value2. Друге значення перетворює перше.
B Сім

Для тих, хто шукає зворотне, це Rack::Utils.build_nested_query(params)(або Rack::Utils.build_query(params)якщо його розібрали Rack::Utils.parse_query).
zelanix

99

Просто вдосконалено за допомогою відповіді Леві вище -

Rack::Utils.parse_query URI("http://example.com?par=hello&par2=bye").query

Для такого рядка, як вище URL, він повернеться

{ "par" => "hello", "par2" => "bye" } 

7
чудова відповідь. просто, обробляє повну URL-адресу, як оп запитує, а значення результату - це рядки замість масивів, як у інших відповідях. Дякую.
jackocnr

3
Як я коментував вище, для тих, хто шукає зворотне, це Rack::Utils.build_query(params).
zelanix

1
Остерігайтеся - не зовсім зворотна, принаймні не в Ruby 1.8.7 / Rails 2.3. Рядок запиту foo [] = 1 & foo [] = 2 правильно розбирається як {"foo" => ["1", "2"]}, але build_query перетворює це на "foo = 1 & foo = 2", який при розборі знову поступається {"foo" => "2"}.
Raels

45

Для отримання чистого розчину Ruby , поєднують URI.parseз CGI.parse(це може бути використано , навіть якщо Rails / стійки і т.д., не обов'язково):

CGI.parse(URI.parse(url).query) 
# =>  {"name1" => ["value1"], "name2" => ["value1", "value2", ...] }

33

Існує не один спосіб вирішити свою проблему. Інші показали вам деякі хитрощі. Я знаю ще одну хитрість. Ось моя спроба: -

require 'uri'
url = "http://www.example.com/something?param1=value1&param2=value2&param3=value3"
uri = URI(url)
# => #<URI::HTTP:0x89e4898 URL:http://www.example.com/something?param1=value1&param2=value2&param3=value3>
URI::decode_www_form(uri.query).to_h # if you are in 2.1 or later version of Ruby
# => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"}
Hash[URI::decode_www_form(uri.query)] # if you are below 2.1 version of Ruby
# => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"}

Прочитайте метод документації ::decode_www_form.


13

Ознайомтеся з адресною дорогоцінним каменем - популярною заміною URI-модуля Ruby, який спрощує аналіз запитів:

require "addressable/uri"
uri = Addressable::URI.parse("http://www.example.com/something?param1=value1&param2=value2&param3=value3")
uri.query_values['param1']
=> 'value1'

(Очевидно, він також обробляє парам кодування / декодування, на відміну від URI)


-3

У вашому контролері ви повинні мати доступ до словника (хеш), який називається params. Отже, якщо ви знаєте, що називають кожен параметр запиту, тоді просто зробіть params[:param1]доступ до нього ... Якщо ви не знаєте, що таке назви параметрів, ви можете перейти до словника та отримати ключі.

Деякі прості приклади тут .


Добре, я це знав, він добре працює в контролері із запитуваною URL-адресою, але як це зробити для інших довільних URL-адрес?
Флаку
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.