Извлечь имя хоста из строки
Я хотел бы сопоставить только корень URL-адреса, а не весь URL-адрес из текстовой строки. Учитывая:
http://www.youtube.com/watch?v=ClkQA2Lb_iE
http://youtu.be/ClkQA2Lb_iE
http://www.example.com/12xy45
http://example.com/random
Я хочу получить 2 последних экземпляра, разрешающих домен www.example.com
или example.com
.
Я слышал, что регулярное выражение медленное, и это будет мое второе выражение регулярных выражений на странице, так что если все равно это сделать без регулярного выражения, дайте мне знать.
Я ищу версию JS/jQuery этого решения.
Ответы
Ответ 1
Я рекомендую использовать пакет npm psl (Public Suffix List). "Общий список суффиксов" - это список всех действительных суффиксов и правил домена, не только доменов верхнего уровня с кодом страны, но и символов Юникода, которые будут считаться корневым доменом (т.е. Www. 食 狮. 公司.cn, bc kobe.jp и т.д.). Подробнее об этом здесь.
Попробуйте:
npm install --save psl
Затем с моей реализацией "extractHostname" запустите:
let psl = require('psl');
let url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
psl.get(extractHostname(url)); // returns youtube.com
Я не могу использовать пакет npm, поэтому ниже тестирует только extractHostname.
function extractHostname(url) {
var hostname;
//find & remove protocol (http, ftp, etc.) and get hostname
if (url.indexOf("//") > -1) {
hostname = url.split('/')[2];
}
else {
hostname = url.split('/')[0];
}
//find & remove port number
hostname = hostname.split(':')[0];
//find & remove "?"
hostname = hostname.split('?')[0];
return hostname;
}
//test the code
console.log("== Testing extractHostname: ==");
console.log(extractHostname("http://www.blog.classroom.me.uk/index.php"));
console.log(extractHostname("http://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("https://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("ftps://ftp.websitename.com/dir/file.txt"));
console.log(extractHostname("websitename.com:1234/dir/file.txt"));
console.log(extractHostname("ftps://websitename.com:1234/dir/file.txt"));
console.log(extractHostname("example.com?param=value"));
console.log(extractHostname("https://facebook.github.io/jest/"));
console.log(extractHostname("//youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("http://localhost:4200/watch?v=ClkQA2Lb_iE"));
Ответ 2
Чистый трюк без использования регулярных выражений:
var tmp = document.createElement ('a');
; tmp.href = "http://www.example.com/12xy45";
// tmp.hostname will now contain 'www.example.com'
// tmp.host will now contain hostname and port 'www.example.com:80'
Оберните вышеприведенную функцию, например, ниже, и у вас есть превосходный способ вырвать часть домена из URI.
function url_domain(data) {
var a = document.createElement('a');
a.href = data;
return a.hostname;
}
Ответ 3
Попробуйте следующее:
var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var domain = matches && matches[1]; // domain will be null if no match is found
Если вы хотите исключить порт из вашего результата, используйте это выражение вместо:
/^https?\:\/\/([^\/:?#]+)(?:[\/:?#]|$)/i
Изменить: Чтобы предотвратить совпадение определенных доменов, используйте отрицательный результат. (?!youtube.com)
/^https?\:\/\/(?!(?:www\.)?(?:youtube\.com|youtu\.be))([^\/:?#]+)(?:[\/:?#]|$)/i
Ответ 4
Нет необходимости разбирать строку, просто передайте свой URL в качестве аргумента в конструктор URL
:
var url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
var hostname = (new URL(url)).hostname;
assert(hostname === 'www.youtube.com');
Ответ 5
Анализ URL-адреса может быть сложным, поскольку вы можете иметь номера портов и специальные символы. Поэтому я рекомендую использовать что-то вроде parseUri, чтобы сделать это за вас. Я сомневаюсь, что производительность будет проблемой, если вы не разберете сотни URL-адресов.
Ответ 6
Используйте URL.hostname
для удобства чтения
В эпоху Вавилона самое чистое и простое решение - использовать URL.hostname
.
const getHostname = (url) => {
// use URL constructor and return hostname
return new URL(url).hostname;
}
// tests
console.log(getHostname("https://stackoverflow.com/questions/8498592/extract-hostname-name-from-string/"));
console.log(getHostname("https://developer.mozilla.org/en-US/docs/Web/API/URL/hostname"));
Ответ 7
Если вы закончите работу на этой странице, и вы ищете лучший REGEX URLS, попробуйте следующее:
^(?:https?:)?(?:\/\/)?([^\/\?]+)
https://regex101.com/r/pX5dL9/1
Он работает для URL-адресов без http://, с http, с https, только с//и не захватывает путь и путь запроса.
Удача
Ответ 8
Я попытался использовать данные решения, выбранный был излишним для моей цели и "Создание элемента" для меня бесполезно.
Он еще не готов для порта в URL. Я надеюсь, что кто-то сочтет это полезным
function parseURL(url){
parsed_url = {}
if ( url == null || url.length == 0 )
return parsed_url;
protocol_i = url.indexOf('://');
parsed_url.protocol = url.substr(0,protocol_i);
remaining_url = url.substr(protocol_i + 3, url.length);
domain_i = remaining_url.indexOf('/');
domain_i = domain_i == -1 ? remaining_url.length - 1 : domain_i;
parsed_url.domain = remaining_url.substr(0, domain_i);
parsed_url.path = domain_i == -1 || domain_i + 1 == remaining_url.length ? null : remaining_url.substr(domain_i + 1, remaining_url.length);
domain_parts = parsed_url.domain.split('.');
switch ( domain_parts.length ){
case 2:
parsed_url.subdomain = null;
parsed_url.host = domain_parts[0];
parsed_url.tld = domain_parts[1];
break;
case 3:
parsed_url.subdomain = domain_parts[0];
parsed_url.host = domain_parts[1];
parsed_url.tld = domain_parts[2];
break;
case 4:
parsed_url.subdomain = domain_parts[0];
parsed_url.host = domain_parts[1];
parsed_url.tld = domain_parts[2] + '.' + domain_parts[3];
break;
}
parsed_url.parent_domain = parsed_url.host + '.' + parsed_url.tld;
return parsed_url;
}
Запуск:
parseURL('https://www.facebook.com/100003379429021_356001651189146');
Результат:
Object {
domain : "www.facebook.com",
host : "facebook",
path : "100003379429021_356001651189146",
protocol : "https",
subdomain : "www",
tld : "com"
}
Ответ 9
Это не полный ответ, но приведенный ниже код вам поможет:
function myFunction() {
var str = "https://www.123rf.com/photo_10965738_lots-oop.html";
matches = str.split('/');
return matches[2];
}
Я хотел бы, чтобы кто-то создал код быстрее моего. Это также помогает улучшить самоопределение.
Ответ 10
Все свойства URL, без зависимостей, нет JQuery, легко понять
Это решение дает ваш ответ плюс дополнительные свойства. Нет необходимости в JQuery или других зависимостях, вставлять и перемещать.
Использование
getUrlParts("https://news.google.com/news/headlines/technology.html?ned=us&hl=en")
Выход
{
"origin": "https://news.google.com",
"domain": "news.google.com",
"subdomain": "news",
"domainroot": "google.com",
"domainpath": "news.google.com/news/headlines",
"tld": ".com",
"path": "news/headlines/technology.html",
"query": "ned=us&hl=en",
"protocol": "https",
"port": 443,
"parts": [
"news",
"google",
"com"
],
"segments": [
"news",
"headlines",
"technology.html"
],
"params": [
{
"key": "ned",
"val": "us"
},
{
"key": "hl",
"val": "en"
}
]
}
код
Код разработан, чтобы быть понятным, а не супер быстро. Его можно назвать легко 100 раз в секунду, поэтому он отлично подходит для интерфейса или нескольких серверов, но не для высокой пропускной способности.
function getUrlParts(fullyQualifiedUrl) {
var url = {},
tempProtocol
var a = document.createElement('a')
// if doesn't start with something like https:// it not a url, but try to work around that
if (fullyQualifiedUrl.indexOf('://') == -1) {
tempProtocol = 'https://'
a.href = tempProtocol + fullyQualifiedUrl
} else
a.href = fullyQualifiedUrl
var parts = a.hostname.split('.')
url.origin = tempProtocol ? "" : a.origin
url.domain = a.hostname
url.subdomain = parts[0]
url.domainroot = ''
url.domainpath = ''
url.tld = '.' + parts[parts.length - 1]
url.path = a.pathname.substring(1)
url.query = a.search.substr(1)
url.protocol = tempProtocol ? "" : a.protocol.substr(0, a.protocol.length - 1)
url.port = tempProtocol ? "" : a.port ? a.port : a.protocol === 'http:' ? 80 : a.protocol === 'https:' ? 443 : a.port
url.parts = parts
url.segments = a.pathname === '/' ? [] : a.pathname.split('/').slice(1)
url.params = url.query === '' ? [] : url.query.split('&')
for (var j = 0; j < url.params.length; j++) {
var param = url.params[j];
var keyval = param.split('=')
url.params[j] = {
'key': keyval[0],
'val': keyval[1]
}
}
// domainroot
if (parts.length > 2) {
url.domainroot = parts[parts.length - 2] + '.' + parts[parts.length - 1];
// check for country code top level domain
if (parts[parts.length - 1].length == 2 && parts[parts.length - 1].length == 2)
url.domainroot = parts[parts.length - 3] + '.' + url.domainroot;
}
// domainpath (domain+path without filenames)
if (url.segments.length > 0) {
var lastSegment = url.segments[url.segments.length - 1]
var endsWithFile = lastSegment.indexOf('.') != -1
if (endsWithFile) {
var fileSegment = url.path.indexOf(lastSegment)
var pathNoFile = url.path.substr(0, fileSegment - 1)
url.domainpath = url.domain
if (pathNoFile)
url.domainpath = url.domainpath + '/' + pathNoFile
} else
url.domainpath = url.domain + '/' + url.path
} else
url.domainpath = url.domain
return url
}
Ответ 11
String.prototype.trim = function(){return his.replace(/^\s+|\s+$/g,"");}
function getHost(url){
if("undefined"==typeof(url)||null==url) return "";
url = url.trim(); if(""==url) return "";
var _host,_arr;
if(-1<url.indexOf("://")){
_arr = url.split('://');
if(-1<_arr[0].indexOf("/")||-1<_arr[0].indexOf(".")||-1<_arr[0].indexOf("\?")||-1<_arr[0].indexOf("\&")){
_arr[0] = _arr[0].trim();
if(0==_arr[0].indexOf("//")) _host = _arr[0].split("//")[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
else return "";
}
else{
_arr[1] = _arr[1].trim();
_host = _arr[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
}
}
else{
if(0==url.indexOf("//")) _host = url.split("//")[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
else return "";
}
return _host;
}
function getHostname(url){
if("undefined"==typeof(url)||null==url) return "";
url = url.trim(); if(""==url) return "";
return getHost(url).split(':')[0];
}
function getDomain(url){
if("undefined"==typeof(url)||null==url) return "";
url = url.trim(); if(""==url) return "";
return getHostname(url).replace(/([a-zA-Z0-9]+.)/,"");
}
Ответ 12
function hostname(url) {
var match = url.match(/:\/\/(www[0-9]?\.)?(.[^/:]+)/i);
if ( match != null && match.length > 2 && typeof match[2] === 'string' && match[2].length > 0 ) return match[2];
}
Приведенный выше код успешно проанализирует имена хостов для следующих примеров URL:
http://WWW.first.com/folder/page.htmlfirst.com
http://mail.google.com/folder/page.htmlmail.google.com
https://mail.google.com/folder/page.htmlmail.google.com
http://www2.somewhere.com/folder/page.html?q=1somewhere.com
https://www.another.eu/folder/page.html?q=1another.eu
Оригинальный кредит распространяется на: http://www.primaryobjects.com/CMS/Article145
Ответ 13
Хорошо, я знаю, что это старый вопрос, но я сделал суперэффективный анализатор URL-адресов, поэтому я решил поделиться им.
Как вы можете видеть, структура функции очень странная, но она эффективна. Никакие функции прототипа не используются, строка не повторяется более одного раза, и никакой символ не обрабатывается больше, чем необходимо.
function getDomain(url) {
var dom = "", v, step = 0;
for(var i=0,l=url.length; i<l; i++) {
v = url[i]; if(step == 0) {
//First, skip 0 to 5 characters ending in ':' (ex: 'https://')
if(i > 5) { i=-1; step=1; } else if(v == ':') { i+=2; step=1; }
} else if(step == 1) {
//Skip 0 or 4 characters 'www.'
//(Note: Doesn't work with www.com, but that domain isn't claimed anyway.)
if(v == 'w' && url[i+1] == 'w' && url[i+2] == 'w' && url[i+3] == '.') i+=4;
dom+=url[i]; step=2;
} else if(step == 2) {
//Stop at subpages, queries, and hashes.
if(v == '/' || v == '?' || v == '#') break; dom += v;
}
}
return dom;
}
Ответ 14
Ищет решение этой проблемы сегодня. Ни один из вышеупомянутых ответов, казалось, не удовлетворял. Мне нужно решение, которое может быть одним лайнером, без условной логики и ничего, что должно было быть обернуто функцией.
Вот что я придумал, кажется, работает очень хорошо:
hostname="http://www.example.com:1234"
hostname.split("//").slice(-1)[0].split(":")[0].split('.').slice(-2).join('.') // gives "example.com"
Может показаться сложным на первый взгляд, но он работает довольно просто; ключ использует "slice (-n)" в нескольких местах, где нужно извлечь большую часть из конца разделенного массива (и [0], чтобы получить от передней части разбитого массива).
Каждый из этих тестов возвращает "example.com":
"http://example.com".split("//").slice(-1)[0].split(":")[0].split('.').slice(-2).join('.')
"http://example.com:1234".split("//").slice(-1)[0].split(":")[0].split('.').slice(-2).join('.')
"http://www.example.com:1234".split("//").slice(-1)[0].split(":")[0].split('.').slice(-2).join('.')
"http://foo.www.example.com:1234".split("//").slice(-1)[0].split(":")[0].split('.').slice(-2).join('.')
Ответ 15
Здесь однострочный jQuery:
$('<a>').attr('href', url).prop('hostname');
Ответ 16
oneline с jquery
$('<a>').attr('href', document.location.href).prop('hostname');
Ответ 17
// use this if you know you have a subdomain
// www.domain.com -> domain.com
function getDomain() {
return window.location.hostname.replace(/([a-zA-Z0-9]+.)/,"");
}
Ответ 18
Я лично много разбирался в этом решении, и лучший, который я смог найти, - это фактически проверка браузера CloudFlare:
function getHostname(){
secretDiv = document.createElement('div');
secretDiv.innerHTML = "<a href='/'>x</a>";
secretDiv = secretDiv.firstChild.href;
var HasHTTPS = secretDiv.match(/https?:\/\//)[0];
secretDiv = secretDiv.substr(HasHTTPS.length);
secretDiv = secretDiv.substr(0, secretDiv.length - 1);
return(secretDiv);
}
getHostname();
Я переписал переменные, чтобы он был более "человечным", но он лучше работал, чем ожидалось.
Ответ 19
Ну, делать регулярное выражение будет намного проще:
mainUrl = "http://www.mywebsite.com/mypath/to/folder";
urlParts = /^(?:\w+\:\/\/)?([^\/]+)(.*)$/.exec(mainUrl);
host = Fragment[1]; // www.mywebsite.com
Ответ 20
Короче говоря, вы можете сделать это
var url = "http://www.someurl.com/support/feature"
function getDomain(url){
domain=url.split("//")[1];
return domain.split("/")[0];
}
eg:
getDomain("http://www.example.com/page/1")
output:
"www.example.com"
Использовать функцию выше для получения имени домена
Ответ 21
Parse-Urls - это библиотека JavaScript с наиболее надежными шаблонами
Вот краткое описание возможностей:
Глава 1. Нормализация или разбор одного URL
Глава 2. Извлечение всех URL-адресов
Глава 3. Извлечение URI с определенными именами
Глава 4. Извлечение всех нечетких URL
Глава 5. Выделите все URL в тексте
Глава 6. Извлечение всех URL в необработанном HTML или XML
Ответ 22
Использование строковых методов вместе с фильтром:
hostName = (url) => url.indexOf('www') > -1 ?
url.split("/").filter(x => !!x)[1].substring(4) :
url.split("/").filter(x => !!x)[1]
console.log(hostName('https://www.website.com/sub/file.html'));
console.log(hostName('http://website.co.uk'));
console.log(hostName('http://website.com'));
// for invalid link, hostname is again extracted
console.log(hostName('http:/website.com'));
Ответ 23
код:
var regex = /\w+.(com|co\.kr|be)/ig;
var urls = ['http://www.youtube.com/watch?v=ClkQA2Lb_iE',
'http://youtu.be/ClkQA2Lb_iE',
'http://www.example.com/12xy45',
'http://example.com/random'];
$.each(urls, function(index, url) {
var convertedUrl = url.match(regex);
console.log(convertedUrl);
});
Результат:
youtube.com
youtu.be
example.com
example.com
Ответ 24
Попробуйте ввести код для точного имени домена с помощью regex,
Строка line = " http://www.youtube.com/watch?v=ClkQA2Lb_iE";
String pattern3="([\\w\\W]\\.)+(.*)?(\\.[\\w]+)";
Pattern r = Pattern.compile(pattern3);
Matcher m = r.matcher(line);
if (m.find( )) {
System.out.println("Found value: " + m.group(2) );
} else {
System.out.println("NO MATCH");
}