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

我正在循环一系列的url,并想要清理它们。 我有以下代码:

# 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 

如何对此进行扩展以删除某些url中存在的子网域?

我刚刚写了一个名为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" 

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

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

Firefox通过有效的顶级域名过滤来解决这个问题,并且他们维护所有这些域名的列表。 有关更多信息,请访问publicsuffix.org 。

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

更新 :有C,Perl和PHP库可以执行此操作。 给定C版本,您可以创建Ruby扩展。 或者,您可以将代码移植到Ruby。

对于后代,这是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" 

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

准备复杂的正则表达式? 🙂

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

我们将其分为两部分。 ^(?:(?>[a-z0-9-]*\.)+?|)将通过匹配一个或多个字符组后跟一个点来收集子域名(贪婪地,这里所有子域都匹配) 。 在没有子域(例如foo.com)的情况下需要空的交替。 ([a-z0-9-]+\.(?>[az]*(?>\.[az]{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 abcdefoo.com => foo.com abcdefoo.co.uk => foo.co.uk 

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

就像是:

 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’部分之前。

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

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

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

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

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

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