Удалить поддомен из строки в ruby - PullRequest
7 голосов
/ 11 июня 2009

Я перебираю серию 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?

Ответы [ 8 ]

28 голосов
/ 12 декабря 2009

Я только что написал библиотеку для этого под названием 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"
6 голосов
/ 11 июня 2009

Это сложная проблема. Некоторые домены верхнего уровня не принимают регистрации на втором уровне.

Сравните example.com и example.co.uk. Если вы просто удалите все, кроме двух последних доменов, вы получите example.com и co.uk, что никогда не может быть намерением.

Firefox решает эту проблему путем фильтрации по эффективному домену верхнего уровня , и они поддерживают список всех этих доменов . Больше информации на publicsuffix.org .

Вы можете использовать этот список, чтобы отфильтровать все, кроме домена справа рядом с действующим TLD. Я не знаю ни одной библиотеки Ruby, которая бы это делала, но было бы неплохо выпустить ее!

Обновление : есть C, Perl и PHP библиотеки , которые делают это. Учитывая версию C, вы можете создать расширение для Ruby. Кроме того, вы можете перенести код на Ruby.

5 голосов
/ 21 октября 2014

Для потомков, вот обновление с октября 2014 года:

Я искал более актуальную зависимость, на которую можно было бы положиться, и нашел гем public_suffix ( 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 голосов
/ 12 июня 2009

Регулярное выражение, которое вам понадобится, может быть немного сложным, потому что имена хостов могут быть бесконечно сложными - у вас может быть несколько поддоменов (например, 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!

2 голосов
/ 11 июня 2009

Что-то вроде:

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».

1 голос
/ 11 июня 2009

Обнаружение субдомена URL-адреса нетривиально в общем смысле - это просто, если вы просто рассмотрите основные из них, но как только вы попадаете на международную территорию, это становится непросто.

Редактировать : рассмотреть такие вещи, как http://mylocalschool.k12.oh.us и др.

0 голосов
/ 18 апреля 2017

За эти годы я много боролся с этим при написании различных и разных сканеров и скребков. Моя любимая жемчужина для решения этой проблемы - FuzzyUrl от Pete Gamache: https://github.com/gamache/fuzzyurl. Доступно для Ruby, JavaScript и Elixir.

0 голосов
/ 20 ноября 2014

Почему бы просто не убрать .com или .co.uk, а затем разделить на '.' и получить последний элемент?

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

Должен сказать, что это кажется хакерским. Есть ли другие домены, как .co.uk?

...