在Ruby中提取字符串中的所有URL

时间:2010-02-19 15:41:00

标签: ruby regex 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']

以上代码似乎无法正常工作。有谁知道我做错了什么?

由于

4 个答案:

答案 0 :(得分:44)

易:

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"] 

答案 1 :(得分: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}

答案 2 :(得分:5)

一种不同的方法,来自完美 - 是好的敌人的思想学派:

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

答案 3 :(得分: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