как получить доменное имя из URL - PullRequest
46 голосов
/ 20 февраля 2009

Как я могу получить доменное имя из строки URL?

Примеры:

+----------------------+------------+
| input                | output     |
+----------------------+------------+
| www.google.com       | google     |
| www.mail.yahoo.com   | mail.yahoo |
| www.mail.yahoo.co.in | mail.yahoo |
| www.abc.au.uk        | abc        |
+----------------------+------------+

Связанный:

Ответы [ 18 ]

40 голосов
/ 20 февраля 2009

Однажды мне пришлось написать такое регулярное выражение для компании, в которой я работал. Решение было таким:

  • Получите список всех доступных нДВУ и рДВУ . Ваша первая остановка должна быть IANA . С первого взгляда список от Mozilla выглядит великолепно, но, к примеру, в нем отсутствует ac.uk, поэтому его нельзя использовать.
  • Присоединяйтесь к списку, как пример ниже. Предупреждение: Заказ важен! Если org.uk появится после uk , тогда example.org.uk будет соответствовать org вместо example,

Пример регулярного выражения:

.*([^\.]+)(com|net|org|info|coop|int|co\.uk|org\.uk|ac\.uk|uk|__and so on__)$

Это сработало очень хорошо, а также соответствовало странным, неофициальным верхним уровням, таким как de.com и друзьям.

Верх:

  • Очень быстро, если регулярное выражение оптимально упорядочено

Недостатком этого решения, конечно, является:

  • Рукописное регулярное выражение, которое должно обновляться вручную, если ccTLD меняются или добавляются. Утомительная работа!
  • Очень большое регулярное выражение, поэтому не очень читабельное.
12 голосов
/ 20 февраля 2009
/^(?:www\.)?(.*?)\.(?:com|au\.uk|co\.in)$/
8 голосов
/ 11 июля 2017

Точное извлечение доменного имени может быть довольно сложным, в основном потому, что расширение домена может содержать 2 части (например, .com.au или .co.uk), а поддомен (префикс) может присутствовать или не присутствовать. Перечисление всех доменных расширений не вариант, потому что их сотни. Например, EuroDNS.com перечисляет более 800 доменных имен.

Поэтому я написал короткую функцию php, которая использует parse_url () и некоторые наблюдения о расширениях домена для точного извлечения компонентов url и имени домена. Функция выглядит следующим образом:

function parse_url_all($url){
    $url = substr($url,0,4)=='http'? $url: 'http://'.$url;
    $d = parse_url($url);
    $tmp = explode('.',$d['host']);
    $n = count($tmp);
    if ($n>=2){
        if ($n==4 || ($n==3 && strlen($tmp[($n-2)])<=3)){
            $d['domain'] = $tmp[($n-3)].".".$tmp[($n-2)].".".$tmp[($n-1)];
            $d['domainX'] = $tmp[($n-3)];
        } else {
            $d['domain'] = $tmp[($n-2)].".".$tmp[($n-1)];
            $d['domainX'] = $tmp[($n-2)];
        }
    }
    return $d;
}

Эта простая функция будет работать практически во всех случаях. Есть несколько исключений, но они очень редки.

Для демонстрации / тестирования этой функции вы можете использовать следующее:

$urls = array('www.test.com', 'test.com', 'cp.test.com' .....);
echo "<div style='overflow-x:auto;'>";
echo "<table>";
echo "<tr><th>URL</th><th>Host</th><th>Domain</th><th>Domain X</th></tr>";
foreach ($urls as $url) {
    $info = parse_url_all($url);
    echo "<tr><td>".$url."</td><td>".$info['host'].
    "</td><td>".$info['domain']."</td><td>".$info['domainX']."</td></tr>";
}
echo "</table></div>";

Вывод будет следующим для перечисленных URL:

enter image description here

Как видите, имя домена и имя домена без расширения последовательно извлекаются независимо от того, какой URL-адрес представлен функции.

Надеюсь, это поможет.

4 голосов
/ 10 сентября 2015

Есть два способа

Использование сплит

Тогда просто разбери эту строку

var domain;
//find & remove protocol (http, ftp, etc.) and get domain
if (url.indexOf('://') > -1) {
    domain = url.split('/')[2];
} if (url.indexOf('//') === 0) {
    domain = url.split('/')[2];
} else {
    domain = url.split('/')[0];
}

//find & remove port number
domain = domain.split(':')[0];

Использование Regex

 var r = /:\/\/(.[^/]+)/;
 "http://stackoverflow.com/questions/5343288/get-url".match(r)[1] 
 => stackoverflow.com

Надеюсь, это поможет

4 голосов
/ 20 февраля 2009

Я не знаю ни одной библиотеки, но манипулирование строками доменных имен достаточно просто.

Трудная часть - знать, находится ли имя на втором или третьем уровне. Для этого вам понадобится файл данных, который вы храните (например, для .uk это не всегда третий уровень, некоторые организации (например, bl.uk, jet.uk) существуют на втором уровне).

Источник Firefox от Mozilla содержит такой файл данных, проверьте лицензирование Mozilla, чтобы узнать, можете ли вы использовать его повторно.

3 голосов
/ 19 июля 2010
import urlparse

GENERIC_TLDS = [
    'aero', 'asia', 'biz', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'jobs', 
    'mil', 'mobi', 'museum', 'name', 'net', 'org', 'pro', 'tel', 'travel', 'cat'
    ]

def get_domain(url):
    hostname = urlparse.urlparse(url.lower()).netloc
    if hostname == '':
        # Force the recognition as a full URL
        hostname = urlparse.urlparse('http://' + uri).netloc

    # Remove the 'user:passw', 'www.' and ':port' parts
    hostname = hostname.split('@')[-1].split(':')[0].lstrip('www.').split('.')

    num_parts = len(hostname)
    if (num_parts < 3) or (len(hostname[-1]) > 2):
        return '.'.join(hostname[:-1])
    if len(hostname[-2]) > 2 and hostname[-2] not in GENERIC_TLDS:
        return '.'.join(hostname[:-1])
    if num_parts >= 3:
        return '.'.join(hostname[:-2])

Этот код не гарантирует работу со всеми URL-адресами и не фильтрует те, которые грамматически правильны, но недействительны, как, например, «example.uk».

Однако в большинстве случаев он справится с работой.

2 голосов
/ 11 ноября 2013

По сути, вы хотите:

google.com        -> google.com    -> google
www.google.com    -> google.com    -> google
google.co.uk      -> google.co.uk  -> google
www.google.co.uk  -> google.co.uk  -> google
www.google.org    -> google.org    -> google
www.google.org.uk -> google.org.uk -> google

Дополнительно:

www.google.com     -> google.com    -> www.google
images.google.com  -> google.com    -> images.google
mail.yahoo.co.uk   -> yahoo.co.uk   -> mail.yahoo
mail.yahoo.com     -> yahoo.com     -> mail.yahoo
www.mail.yahoo.com -> yahoo.com     -> mail.yahoo

Вам не нужно создавать постоянно меняющееся регулярное выражение, поскольку 99% доменов будут сопоставлены правильно, если вы просто посмотрите на 2-ю последнюю часть имени:

(co|com|gov|net|org)

Если это одна из них, то вам нужно сопоставить 3 точки, иначе 2. Простая. Теперь мое волшебство с регулярными выражениями не подходит для других SO, поэтому я нашел лучший способ добиться этого с помощью некоторого кода, предполагая, что вы уже удалили путь:

 my @d=split /\./,$domain;                # split the domain part into an array
 $c=@d;                                   # count how many parts
 $dest=$d[$c-2].'.'.$d[$c-1];             # use the last 2 parts
 if ($d[$c-2]=~m/(co|com|gov|net|org)/) { # is the second-last part one of these?
   $dest=$d[$c-3].'.'.$dest;              # if so, add a third part
 };
 print $dest;                             # show it

Чтобы просто получить имя, согласно вашему вопросу:

 my @d=split /\./,$domain;                # split the domain part into an array
 $c=@d;                                   # count how many parts
 if ($d[$c-2]=~m/(co|com|gov|net|org)/) { # is the second-last part one of these?
   $dest=$d[$c-3];                        # if so, give the third last
   $dest=$d[$c-4].'.'.$dest if ($c>3);    # optional bit
 } else {
   $dest=$d[$c-2];                        # else the second last
   $dest=$d[$c-3].'.'.$dest if ($c>2);    # optional bit 
 };
 print $dest;                             # show it

Мне нравится этот подход, потому что он не требует обслуживания. Если вы не хотите проверить, что это действительно законный домен, но это бессмысленно, потому что вы, скорее всего, используете это только для обработки файлов журналов, и недопустимый домен в первую очередь туда не попадет.

Если вы хотите сопоставить «неофициальные» субдомены, такие как bozo.za.net или bozo.au.uk, bozo.msf.ru просто добавьте (za | au | msf) к регулярному выражению.

Мне бы очень хотелось, чтобы кто-то сделал все это, используя просто регулярное выражение, я уверен, что это возможно.

2 голосов
/ 09 марта 2012

Невозможно без использования списка TLD сравнивать с существующими во многих случаях, такими как http://www.db.de/ или http://bbc.co.uk/, которые будут интерпретироваться регулярным выражением как домены db.de (правильно) и co.uk (неверно).

Но даже при этом вы не добьетесь успеха, если ваш список также не содержит SLD. URL-адреса, такие как http://big.uk.com/ и http://www.uk.com/, будут интерпретироваться как uk.com (первый домен - big.uk.com).

Из-за этого все браузеры используют общедоступный список суффиксов Mozilla:

https://en.wikipedia.org/wiki/Public_Suffix_List

Вы можете использовать его в своем коде, импортировав его по этому адресу:

http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1

Не стесняйтесь расширять мою функцию только для извлечения доменного имени. Он не будет использовать регулярные выражения и это быстро:

http://www.programmierer -forum.de / domainnamen-ermitteln-t244185.htm # 3471878

1 голос
/ 04 ноября 2010

/[^w{3}\.]([a-zA-Z0-9]([a-zA-Z0-9\-]{0,65}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}/gim

использование этого регулярного выражения javascript игнорирует www и следующую точку, сохраняя домен без изменений. также правильно соответствует no www и cc tld

0 голосов
/ 24 мая 2017
  1. как это

    =((?:(?:(?:http)s?:)?\/\/)?(?:(?:[a-zA-Z0-9]+)\.?)*(?:(?:[a-zA-Z0-9]+))\.[a-zA-Z0-9]{2,3}) (вы можете добавить «\ /» в конец шаблона

  2. если ваша цель состоит в том, чтобы избавиться от URL, переданного в качестве параметра, вы можете добавить знак равенства в качестве первого символа, например:

    = ((:( :( ?: HTTP) с:??)? //) (?: (?: [A-Za-Z0-9] +).??) * (:( ?:. [A-Za-Z0-9] +)) [A-Za-Z0-9] {2,3} /)

    и заменить на "/"

Цель этого примера - избавиться от любого доменного имени независимо от формы, в которой оно появляется. (т.е. чтобы параметры URL не включали доменные имена во избежание атаки xss)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...