从ruby中的字符串中删除子域

时间:2009-06-11 19:33:25

标签: ruby url dns subdomain uri

我正在循环播放一系列网址并想要清理它们。我有以下代码:

# Parse url to remove http, path and check format
o_url = URI.parse(node.attributes['href'])

# Remove www
new_url = o_url.host.gsub('www.', '').strip

如何扩展此功能以删除某些网址中存在的子域?

8 个答案:

答案 0 :(得分:28)

我刚写了一个名为Domainatrix的库。您可以在此处找到它:http://github.com/pauldix/domainatrix

require 'rubygems'
require 'domainatrix'

url = Domainatrix.parse("http://www.pauldix.net")
url.public_suffix       # => "net"
url.domain    # => "pauldix"
url.canonical # => "net.pauldix"

url = Domainatrix.parse("http://foo.bar.pauldix.co.uk/asdf.html?q=arg")
url.public_suffix       # => "co.uk"
url.domain    # => "pauldix"
url.subdomain # => "foo.bar"
url.path      # => "/asdf.html?q=arg"
url.canonical # => "uk.co.pauldix.bar.foo/asdf.html?q=arg"

答案 1 :(得分:6)

这是一个棘手的问题。某些顶级域名不接受第二级注册。

比较example.comexample.co.uk。如果你只是删除除最后两个域之外的所有内容,那么最终会得到example.com co.uk ,这绝不是意图。

Firefox通过有效的顶级域名进行过滤来解决此问题,并维护all these domains列表。有关更多信息,请访问publicsuffix.org

您可以使用此列表过滤除有效TLD旁边的域之外的所有内容。我不知道有任何Ruby库可以做到这一点,但发布一个是个好主意!

更新:有C, Perl and PHP libraries这样做。给定C版本,您可以创建Ruby扩展。或者,您可以将代码移植到Ruby。

答案 2 :(得分:5)

对于后代,这是2014年10月的更新:

我一直在寻找更依赖的最新依赖项,并找到了public_suffix gem(RubyGems)(GitHub)。通过维护已知公共后缀列表,它正在积极维护并处理所有顶级域和嵌套子域问题。

结合URI.parse剥离协议和路径,它的效果非常好:

❯❯❯ 2.1.2 ❯ PublicSuffix.parse(URI.parse('https://subdomain.google.co.uk/path/on/path').host).domain
=> "google.co.uk"

答案 3 :(得分:3)

这里你需要的正则表达式可能有点棘手,因为主机名可能无限复杂 - 你可能有多个子域(即foo.bar.baz.com)或顶级域(TLD) )可以有多个部分(即www.baz.co.uk)。

准备复杂的正则表达式? :)

re = /^(?:(?>[a-z0-9-]*\.)+?|)([a-z0-9-]+\.(?>[a-z]*(?>\.[a-z]{2})?))$/i
new_url = o_url.host.gsub(re, '\1').strip

让我们将其分为两部分。 ^(?:(?>[a-z0-9-]*\.)+?|)将通过匹配一个或多个字符组后跟一个点来收集子域名(贪婪地,以便在此处匹配所有子域名)。在没有子域(例如foo.com)的情况下,需要空的交替。 ([a-z0-9-]+\.(?>[a-z]*(?>\.[a-z]{2})?))$将收集实际的主机名和TLD。它允许单部分TLD(如.info,.com或.museum)或两部分TLD,其中第二部分是两个字符(如.oh.us或.org.uk)。

我在以下样本上测试了这个表达式:

foo.com => foo.com
www.foo.com => foo.com
bar.foo.com => foo.com
www.foo.ca => foo.ca
www.foo.co.uk => foo.co.uk
a.b.c.d.e.foo.com => foo.com
a.b.c.d.e.foo.co.uk => foo.co.uk

请注意,此正则表达式不能正确匹配具有两个以上“部分”的主机名到TLD!

答案 4 :(得分:2)

类似的东西:

def remove_subdomain(host)
    # Not complete. Add all root domain to regexp
    host.sub(/.*?([^.]+(\.com|\.co\.uk|\.uk|\.nl))$/, "\\1")
end

puts remove_subdomain("www.example.com") # -> example.com
puts remove_subdomain("www.company.co.uk") # -> company.co.uk
puts remove_subdomain("www.sub.domain.nl") # -> domain.nl

您仍需要添加您认为是根域的所有(根)域。因此'.uk'可能是根域,但您可能希望将主机保留在'.co.uk'部分之前。

答案 5 :(得分:1)

从一般意义上来说,检测URL的子域名是非常重要的 - 如果您只考虑基本的域名,这很容易,但一旦进入国际领域,这就变得棘手了。

修改:考虑像http://mylocalschool.k12.oh.us等人的内容。

答案 6 :(得分:0)

为什么不剥离.com或.co.uk然后拆分'。'并得到最后一个元素?

some_url.host.sub(/(\.co\.uk|\.[^.]*)$/).split('.')[-1] + $1

不得不说它感觉很乱。还有像.co.uk这样的其他域名吗?

答案 7 :(得分:0)

多年来,我在编写各种各样的爬行器和刮刀时,经历了很多努力。我最喜欢的解决这个问题的宝石是Pete Gamache的FuzzyUrl:https://github.com/gamache/fuzzyurl。它适用于Ruby,JavaScript和Elixir。