您将如何解析 Ruby 中的 url 以获取主域?

Posted

技术标签:

【中文标题】您将如何解析 Ruby 中的 url 以获取主域?【英文标题】:How would you parse a url in Ruby to get the main domain? 【发布时间】:2011-10-04 04:36:21 【问题描述】:

我希望能够使用 Ruby 解析任何 URL,以获取没有 www 的域的主要部分(只是 example.com

【问题讨论】:

在匹配最终实体服务器证书时,Ruby 无法在所有条件下正确处理主机名匹配。我知道一些意想不到的荒谬结果。 【参考方案1】:

请注意没有算法方法可以找到可以为特定***域注册域的***别(每个注册机构的政策不同),唯一的方法是创建所有***域的列表以及可以注册域的级别。

这就是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"

【讨论】:

最后一个domain.domain #=> "google.com" 是错误还是我不明白什么?? 不,这不是一个错误。第一个domain是一个变量,第二个是方法调用。该变量可以随心所欲地调用。 “这就是公共后缀列表存在的原因......” - 我不相信“主”域和 PSL 中的条目是一回事。 PSL 包括 gTLD、ccTLD 和 cookie 路径。确定“主”域不需要 cookie 路径,它可能会导致错误的结果。 @SimoneCarletti 我最初的评论是不久前的,但我的意思是在最后一个例子中.co.uk,突然变成.com 我会将domain.domain 重命名为domain.name【参考方案2】:

这应该适用于几乎任何 URL:

# 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'

【讨论】:

如果url 只是www.example.com 这可能行不通,URI 对没有方案的 URI 反应不佳。 您可以通过在u = URI.parse(url) 之后检查u.scheme 然后在必要时添加一个方案并重新解析来解决这个问题。 我认为这些变得太复杂了。这应该可以工作:URI('http://www.example.com').host.match(/[^\.]+\.\w+$/).to_s. @Chip 嘿,你的正则表达式无法检查ccTLD 如果URI('http://www.example.co.kr').host.match(/[^\.]+\.\w+$/).to_s 编码,则输出=> "co.kr"【参考方案3】:

简短说明:为了克服 Mischas 第二个示例中对 url 的第二次解析,您可以进行字符串比较而不是 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,这是广泛的标准。但是,如果您将使用它更通用(例如用于 ftp 链接),则必须相应地进行调整。

【讨论】:

【参考方案4】:

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["***.com"]
# => "***.com"

我希望这对其他人有所帮助。

【讨论】:

【参考方案5】:

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

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

【讨论】:

在这个上返回 nil:moebel-turflon.de/karriere/jobs/136【参考方案6】:

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

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

或者

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

【讨论】:

绝对不是——这真的取决于你的输入——你一次只接收一个网址作为输入吗?网址有相对路径吗?他们总是带有www 作为子域吗?他们总是有一个子域吗?它们都是http 网址还是您获得带有httpsftp 等的网址?还有更多问题可以问 - 这只是为了让你开始:) 这不适用于英国域名co.uk 例如【参考方案7】:

你可以写这个方法:

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"

【讨论】:

这不适用于 ccTLD,例如domain_name("https://www.google.co.uk/?gws_rd=ssl&safe=active&ssui=on") #=> "co" 你是对的,这仅适用于问题的具体示例,也就是说,只是一个示例,在过去的几年里,我假装开发人员应该理解并采取相应的行动。

以上是关于您将如何解析 Ruby 中的 url 以获取主域?的主要内容,如果未能解决你的问题,请参考以下文章

Ruby中数组的深拷贝

Ruby 中的日期时间解析

如何解析 Postgresql JDBC url 以获取主机名、端口和 db_name

如何修复错误:Ruby on Rails 中的“Sass::SyntaxError in Posts#index”?

如何在ruby中获取位图图像?

如何从 C# 中的相对 URL 字符串中获取参数?