我有一些文字内容,其中包含网址列表。
我试图抓住所有的网址并将它们放在一个数组中。
我有这段代码
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']
以上代码似乎无法正常工作。有谁知道我做错了什么?
由于
答案 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