2010-02-19 49 views
5

我有一些文本內容,其中包含一個URL列表。在Ruby中提取字符串中的所有網址

我想抓住所有的URL並將它們放入數組中。

我有這樣的代碼

content = "Here is the list of URLs: http://www.google.com http://www.google.com/index.html" 

urls = content.scan(/^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix) 

我試圖讓最終的結果是:

['http://www.google.com', 'http://www.google.com/index.html'] 

上面的代碼似乎並沒有正常工作。有誰知道我做錯了什麼?

感謝

回答

5

不同的方法,從完美的,是最敵人的最良好的辦學思想:

urls = content.split(/\s+/).find_all { |u| u =~ /^https?:/ } 
+1

我給你簡單。這可能是所有需要的。 – Chowlett 2010-02-19 16:35:58

+1

我畢業於那所學校! – 2012-10-25 00:58:57

+0

這種方法將會錯過許多有效的URL並錯誤地選擇許多無效的URL。 – sferik 2013-01-23 05:47:48

5

我沒有檢查你的正則表達式的語法,但String.scan會產生一個數組,它的每個成員是你的正則表達式匹配組的陣列。所以我希望得到的結果是:

[['http', '.google.com'], ...]

你需要不匹配的組/(?:stuff)/如果你想要你給的格式。

編輯(看正則表達式):此外,你的正則表達式看起來有點不對。您不希望開始和結束錨點(^$),因爲您不希望匹配在content的開始和結束。其次,如果你的([0-9]{1,5})?試圖捕獲一個端口號,我認爲你錯過了一個冒號來區分端口。

進一步編輯,播放後:我想你想是這樣的:

content = "Here is the list of URLs: http://www.google.com http://www.google.com/index.html http://example.com:3000/foo" 
urls = content.scan(/(?:http|https):\/\/[a-z0-9]+(?:[\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(?:(?::[0-9]{1,5})?\/[^\s]*)?/ix) 
# => ["http://www.google.com", "http://www.google.com/index.html", "http://example.com:3000/foo"] 

...但是請注意,它不會匹配純IP地址的網址(例如http://127.0.0.1),因爲TLD的[a-z]{2,5}

42

簡單:

ruby-1.9.2-p136 :006 > require 'uri' 
ruby-1.9.2-p136 :006 > URI.extract(content, ['http', 'https']) 
    => ["http://www.google.com", "http://www.google.com/index.html"] 
+0

爲什麼這不被標記爲正確的答案。 grml – 2015-09-24 04:04:58

+0

這應該被標記爲答案。更優雅。 – adeluccar 2016-06-03 09:14:36

4

只爲你的興趣:

Ruby有一個URI模塊,它有一個正則表達式來實現這樣的事情:

require "uri" 

uris_you_want_to_grap = ['ftp','http','https','ftp','mailto','see'] 

html_string.scan(URI.regexp(uris_you_want_to_grap)) do |*matches| 
    urls << $& 
end 

欲瞭解更多信息,請參閱Ruby Ref:URI