2009-06-11 14 views
7

Estoy recorriendo una serie de URL y quiero limpiarlas. Tengo el siguiente código:Eliminar el subdominio de la cadena en ruby ​​

# 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 

¿Cómo puedo extender esto para eliminar los subdominios que existen en algunas URL?

Respuesta

2

Algo así como:

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 

Todavía es necesario agregar todos (raíz) Dominios se tiene en cuenta dominio raíz. Así que '.uk' podría ser el dominio raíz, pero es probable que desee mantener el host justo antes de la parte '.co.uk'.

1

La detección del subdominio de una URL no es trivial para hacer en un sentido general; es fácil si solo se consideran los básicos, pero una vez que se entra en territorio internacional esto se vuelve complicado.

Editar: Considerar cosas como http://mylocalschool.k12.oh.us et al.

6

Esto es un problema complicado. Algunos dominios de nivel superior no aceptan registros en el segundo nivel.

Comparar example.com y example.co.uk. Si simplemente quita todo excepto los dos últimos dominios, terminaría con example.com y co.uk, lo que nunca puede ser la intención.

Firefox resuelve esto filtrando por dominio de nivel superior efectivo, y mantienen una lista de all these domains. Más información en publicsuffix.org.

Puede usar esta lista para filtrar todo excepto el dominio derecho junto al TLD efectivo. No sé de ninguna biblioteca de Ruby que haga esto, ¡pero sería una gran idea lanzar uno!

Actualización: hay C, Perl and PHP libraries que hacen esto. Dada la versión C, puede crear una extensión Ruby. Alternativamente, podría portar el código a Ruby.

+0

Olvidé ese sitio, buena respuesta –

3

La expresión regular que necesitará aquí puede ser un poco complicada, ya que los nombres de host pueden ser infinitamente complejos: puede tener múltiples subdominios (es decir, foo.bar.baz.com) o el dominio de nivel superior (TLD) puede tener varias partes (es decir, www.baz.co.uk).

¿Listo para una expresión regular compleja? :)

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

Vamos a dividir esto en dos secciones. ^(?:(?>[a-z0-9-]*\.)+?|) recogerá subdominios, haciendo coincidir uno o más grupos de caracteres seguidos de un punto (ávidamente, de forma que todos los subdominios coincidan). La alternancia vacía es necesaria en el caso de que no haya ningún subdominio (como foo.com). ([a-z0-9-]+\.(?>[a-z]*(?>\.[a-z]{2})?))$ recogerá el nombre de host real y el TLD. Permite un TLD de una parte (como .info, .com o .museum) o un TLD de dos partes, donde la segunda parte tiene dos caracteres (como .oh.us o .org.uk).

He probado esta expresión en las siguientes muestras:

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 

Tenga en cuenta que esta expresión regular no coincidirá correctamente los nombres de host que tienen más de dos "partes" en el dominio de nivel superior!

28

Acabo de escribir una biblioteca para hacer esto llamada Domainatrix. Lo puedes encontrar aquí: 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

Esta joya de rubí hace referencia al archivo de datos de Mozilla en publicsuffix.org. – shadowbq

+0

Funciona mejor que URI, en mi experiencia, por ejemplo en videos de YouTube URI elimina el campo? V = ******** dejando solo/watch, mientras que Domainatrix funciona perfectamente – alexvicegrab

4

Para la posteridad, aquí es una actualización desde octubre 2014:

que estaba buscando una dependencia más arriba-hasta la fecha a tener en cuenta y encontrado la gema public_suffix (RubyGems) (GitHub). Se mantiene activamente y maneja todos los problemas de dominio de nivel superior y subdominio anidado manteniendo una lista de los sufijos públicos conocidos.

En combinación con URI.parse para pelar protocolo y caminos, que funciona muy bien:

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

¿Por qué no pele el .com o .es y luego se dividieron en ''. y obtener el último elemento?

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

Tengo que decir que se siente hacky. ¿Hay algún otro dominio como .co.uk?

0

He luchado mucho con esto al escribir varios y diversos rastreadores y raspadores a lo largo de los años. Mi joya favorita para resolver esto es FuzzyUrl de Pete Gamache: https://github.com/gamache/fuzzyurl. Está disponible para Ruby, JavaScript y Elixir.

Cuestiones relacionadas