2014-10-20 78 views
0

我有一個像下面的URL。ruby​​中的正則表達式

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

我需要使用正則表達式只提取播放的ID(即5b35a825-d372-4375-b2f0-f641a38067db)。我該怎麼做?

+2

請注意,由於不必要的限制被添加到問題中,有時您會錯過最佳解決方案的答案。在這種情況下,就是使用正則表達式。換句話說,你的問題是一個XY問題。 – sawa 2014-10-20 12:28:55

+0

請參閱? (參見spickermann的回答) – sawa 2014-10-20 12:36:08

+0

請勿對此使用正則表達式。使用現有的工具,如URI或Addressable :: URI。 – 2014-10-20 14:44:56

回答

4

我不會使用正則表達式來解析url。我會用Ruby的庫來處理網址:

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。 – 2014-10-20 14:48:06

+0

你對@theTinMan。我改變了這一點。 – spickermann 2014-10-20 20:39:21

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 =)[^&] + /]',但我不明白爲什麼使用'[^&] +',而不是'。 +',是必要的。請解釋'&'的作用。 – 2014-10-20 19:14:59

+0

@CarySwoveland ......真的嗎?它不是查詢字符串分隔符嗎?答案中是否已經解釋了?另外,如果你可以解釋_why_,你的版本實際上會更簡單,那就太好了。 – arco444 2014-10-21 08:41:11

+0

我是一個對標記一無所知的Ruby最幸福的人(看起來很奇怪)。這就是爲什麼我不知道查詢字符串分隔符是什麼。我用了「簡化」一詞,因爲我認爲我的建議保存了一個步驟。我現在看到它沒有,因爲你不必使用局部變量'match'。 – 2014-10-21 16:34:21

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

Ruby的內置URI類必須正確分析所需要的一切,拆分和解碼網址:

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" 

如果您使用的是舊版Ruby不支持to_h,請使用:

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

您應該使用URI,r而不是嘗試使用正則表達式來分割/提取,因爲如果任何值不在規範允許的字符範圍內,URI的查詢將被編碼。 URI或Addressable::URI,會將它們解碼爲您的原始值。