你如何解析Ruby中的url以获得主域名?

时间:2011-07-13 04:48:33

标签: ruby-on-rails ruby parsing url dns

我希望能够使用ruby解析任何网址以获取域的主要部分而不使用www(仅限XXXX.com)

7 个答案:

答案 0 :(得分:76)

请注意没有找到可以为特定顶级域名注册域名的最高级别的算法方法(政策因每个注册表而异),唯一的方法是创建所有顶级域名列表以及域名注册级别。

这就是Public Suffix List存在的原因。

我是PublicSuffix的作者,这是一个将域分解为不同部分的Ruby库。

这是一个例子

require 'uri/http'

uri = URI.parse("http://toolbar.google.com")
domain = PublicSuffix.parse(uri.host)
# => "toolbar.google.com"
domain.domain
# => "google.com"

uri = URI.parse("http://www.google.co.uk")
domain = PublicSuffix.parse(uri.host)
# => "www.google.co.uk"
domain.domain
# => "google.co.uk"

答案 1 :(得分:60)

这应该适用于任何网址:

# URL always gets parsed twice
def get_host_without_www(url)
  url = "http://#{url}" if URI.parse(url).scheme.nil?
  host = URI.parse(url).host.downcase
  host.start_with?('www.') ? host[4..-1] : host
end

或者:

# Only parses twice if url doesn't start with a scheme
def get_host_without_www(url)
  uri = URI.parse(url)
  uri = URI.parse("http://#{url}") if uri.scheme.nil?
  host = uri.host.downcase
  host.start_with?('www.') ? host[4..-1] : host
end

您可能必须require 'uri'

答案 2 :(得分:4)

简单说明:要克服Mischas第二个示例中第二次解析网址,您可以进行字符串比较而不是URI.parse。

# Only parses once
def get_host_without_www(url)
  url = "http://#{url}" unless url.start_with?('http')
  uri = URI.parse(url)
  host = uri.host.downcase
  host.start_with?('www.') ? host[4..-1] : host
end

这种方法的缺点是,它将URL限制为基于http(s)的URL,这是广泛的标准。但是如果你将它更通用(f.e. for ftp links),你必须相应调整。

答案 3 :(得分:2)

Addressable可能是2018年的正确答案,尤其是uses the PublicSuffix gem to parse domains

但是,我需要在多个地方,从各种数据源进行这种解析,并发现重复使用有点冗长。所以我创建了一个包装器,Adomain

require 'adomain'

Adomain["https://toolbar.google.com"]
# => "toolbar.google.com"

Adomain["https://www.google.com"]
# => "google.com"

Adomain["stackoverflow.com"]
# => "stackoverflow.com"

我希望这有助于其他人。

答案 4 :(得分:1)

这是一个更适合.co.uk和.com.fr - 类型域

的方法
domain = uri.host[/[^.\s\/]+\.([a-z]{3,}|([a-z]{2}|com)\.[a-z]{2})$/]

答案 5 :(得分:0)

如果网址格式为http://www.google.com,那么您可以执行以下操作:

a = 'http://www.google.com'
puts a.split(/\./)[1] + '.' + a.split(/\./)[2]

或者

a =~ /http:\/\/www\.(.*?)$/
puts $1

答案 6 :(得分:0)

那么您可以编写此方法:

require 'URI'
def domain_name(url, arg={:with_dot_principal=>false})
  arg[:with_dot_principal] ? URI(url).hostname.split('.').last(2).join('.') : URI(url).hostname.split('.').last(2).first
end

并使用:

domain_name("https://www.google.com/?gws_rd=ssl&safe=active&ssui=on")
# => "google"
domain_name("http://google.com", with_dot_principal: true)
# => "google.com"