2014-10-20 2 views
0

У меня есть URL-адрес, как показано ниже.Регулярный экспресс в рубине

/shows/the-ruby-book/meta-programming/?play=5b35a825-d372-4375-b2f0-f641a38067db" 

мне нужно извлечь только идентификатор игры (т.е. 5b35a825-d372-4375-b2f0-f641a38067db), используя регулярное выражение. Как мне это сделать?

+2

Обратите внимание, что иногда вы будете пропускать ответы с лучшими решениями из-за ненужных ограничений, связанных с проблемой. В этом случае используется регулярное выражение. Другими словами, ваш вопрос - проблема XY. – sawa

+0

Видите? (См. Ответ spickermann) – sawa

+0

Не используйте для этого регулярные выражения. Используйте существующие инструменты, такие как URI или Addressable :: URI. –

ответ

4

Я бы не использовал регулярное выражение для анализа URL-адреса. Я хотел бы использовать библиотеки в Ruby для обработки URL-адресов:

require 'uri' 

url = '/shows/the-ruby-book/meta-programming/?play=5b35a825-d372-4375-b2f0-f641a38067db' 

uri = URI.parse(url) 
params = URI::decode_www_form(uri.query).to_h 

params['play'] 
# => 5b35a825-d372-4375-b2f0-f641a38067db 
+0

Вы должны использовать ['URI :: decode_www_form'] (http://www.ruby-doc.org/stdlib-2.1.2/libdoc/uri/rdoc/URI.html#method-c-decode_www_form), а не беспокоиться с CGI. –

+0

Вы правы @ theTinMan. Я изменил это. – spickermann

1

Вы можете сделать:

str = '/shows/the-ruby-book/meta-programming/?play=5b35a825-d372-4375-b2f0-f641a38067db' 
match = str.match(/.*\?play=([^&]+)/) 
puts match[1] 

=> "5b35a825-d372-4375-b2f0-f641a38067db" 

регулярное выражение /.*\?play=([^&]+)/ будет соответствовать все вплоть до ?play=, а затем захватить что-либо, что не является (разделитель параметр строки запроса) а &

матч будет создать MatchData, представленный здесь переменной match, а захваты будут индексом объекта, поэтому ваши согласованные данные доступны по адресу match[1].

+0

Я думаю, что это можно упростить до 'str [/ (? <= \? Play =) [^ &] + /]', но я не понимаю, почему '[^ &] +', а не просто '. + ', необходимо. Пожалуйста, объясните роль '&'. –

+0

@ CarySwoveland ... Серьезно? Разве это не разделитель строк запроса? Разве это еще не объяснено в ответе? Кроме того, было бы хорошо, если бы вы могли объяснить, почему ваша версия на самом деле проще. – arco444

+0

Я рубиновый хоббист, который ничего не знает о разметке (как это ни странно). Вот почему я не знаю, что такое разделитель строк запроса. Я использовал термин «упрощенный», потому что я думал, что мое предложение спасло шаг. Теперь я вижу, что это не так, поскольку вам не нужно было использовать локальную переменную 'match'. –

1
url = '/shows/the-ruby-book/meta-programming/?play=5b35a825-d372-4375-b2f0-f641a38067db' 
url.split("play=")[1] #=> "5b35a825-d372-4375-b2f0-f641a38067db" 
0

рубин встроенный в URI классе есть все необходимое, чтобы правильно разобрать, расщепленные и декодировать URL-адреса:

require 'uri' 

uri = URI.parse('/shows/the-ruby-book/meta-programming/?play=5b35a825-d372-4375-b2f0-f641a38067db') 
URI::decode_www_form(uri.query).to_h['play'] # => "5b35a825-d372-4375-b2f0-f641a38067db" 

Если вы используете старше рубин, который не поддерживает to_h, использование:

Hash[URI::decode_www_form(uri.query)]['play'] # => "5b35a825-d372-4375-b2f0-f641a38067db" 

Вы должны использовать URI, г а не пытаться разделить/извлечь с помощью регулярного выражения, потому что запрос URI будет закодирован, если любые значения не находятся в пределах символов, разрешенных спецификацией. URI или Addressable::URI, будут декодировать их обратно до их первоначальных значений.

Смежные вопросы