Извлечение имени хоста из строки
Я хотел бы соответствовать только корень 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 версию этого решения.
21 ответов:
попробуй:
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; } // To address those who want the "root domain," use this function: function extractRootDomain(url) { var domain = extractHostname(url), splitArr = domain.split('.'), arrLen = splitArr.length; //extracting the root domain here //if there is a subdomain if (arrLen > 2) { domain = splitArr[arrLen - 2] + '.' + splitArr[arrLen - 1]; //check to see if it's using a Country Code Top Level Domain (ccTLD) (i.e. ".me.uk") if (splitArr[arrLen - 2].length == 2 && splitArr[arrLen - 1].length == 2) { //this is using a ccTLD domain = splitArr[arrLen - 3] + '.' + domain; } } return domain; } //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")); //test extractRootDomain console.log("== Testing extractRootDomain: =="); console.log(extractRootDomain("http://www.blog.classroom.me.uk/index.php")); console.log(extractRootDomain("http://www.youtube.com/watch?v=ClkQA2Lb_iE")); console.log(extractRootDomain("https://www.youtube.com/watch?v=ClkQA2Lb_iE")); console.log(extractRootDomain("www.youtube.com/watch?v=ClkQA2Lb_iE")); console.log(extractRootDomain("ftps://ftp.websitename.com/dir/file.txt")); console.log(extractRootDomain("websitename.com:1234/dir/file.txt")); console.log(extractRootDomain("ftps://websitename.com:1234/dir/file.txt")); console.log(extractRootDomain("example.com?param=value")); console.log(extractRootDomain("https://facebook.github.io/jest/")); console.log(extractRootDomain("//youtube.com/watch?v=ClkQA2Lb_iE"));*нажмите "Выполнить фрагмент кода", чтобы увидеть эти методы в действии.
независимо от наличия протокола или даже номера порта, вы можете извлечь домен. Это очень упрощенное, нерегулярное решение, поэтому я думаю, что это будет сделано.
* спасибо @Timmerz, @renoirb, @rineez, @BigDong, @ra00l, @ILikeBeansTacos, @CharlesRobertson за ваши предложения! @Росс-Аллен, спасибо за сообщение об ошибке!
ловкий трюк без использования регулярных выражений:
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; }
попробуйте это:
var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); var domain = matches && matches[1]; // domain will be null if no match is foundесли вы хотите исключить порт из вашего результата, используйте это выражение вместо:
/^https?\:\/\/([^\/:?#]+)(?:[\/:?#]|$)/iEdit: чтобы предотвратить совпадение определенных доменов, используйте отрицательный внешний вид.
(?!youtube.com)/^https?\:\/\/(?!(?:www\.)?(?:youtube\.com|youtu\.be))([^\/:?#]+)(?:[\/:?#]|$)/i
нет необходимости разбирать строку, просто передайте свой URL в качестве аргумента
URLконструктор:var url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE'; var hostname = (new URL(url)).hostname; assert(hostname === 'www.youtube.com');
разбор URL может быть сложным, потому что вы можете иметь номера портов и специальные символы. Как таковой, я рекомендую использовать что-то вроде parseUri сделать это для вас. Я сомневаюсь, что производительность будет проблемой, если вы не разбираете сотни URL-адресов.
Я пытался использовать данные решения, выбранный был излишним для моей цели и" создание элемента " один испортит для меня.
Он еще не готов для порта в 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" }
Если вы в конечном итоге на этой странице, и вы ищете лучшее регулярное выражение URL-адресов попробуйте это:
^(?:https?:)?(?:\/\/)?([^\/\?]+)https://regex101.com/r/pX5dL9/1
Он работает для URL-адресов без http://, с http, с https, только с / / и не захватить путь и путь запроса, а также.
Удачи
Это не полный ответ, но код, приведенный ниже, должен помочь вам:
function myFunction() { var str = "https://www.123rf.com/photo_10965738_lots-oop.html"; matches = str.split('/'); return matches[2]; }Я хотел бы, чтобы кто-то создавал код быстрее, чем мой. Это также помогает улучшить себя.
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]+.)/,""); }
хорошо, я знаю, что это старый вопрос, но я сделал супер-эффективный синтаксический анализатор 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; }
искал решение этой проблемы сегодня. Ни один из вышеприведенных ответов, казалось, не удовлетворил. Я хотел решение, которое может быть одним лайнером, без условной логики и ничего, что должно быть обернуто в функцию.
вот что я придумал, кажется, работает очень хорошо:
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('.')
все свойства 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's 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 }
// 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]+.)/,""); }
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.html first.com
http://mail.google.com/folder/page.html mail.google.com
https://mail.google.com/folder/page.html mail.google.com
http://www2.somewhere.com/folder/page.html?q=1 somewhere.com
оригинальный кредит идет к: http://www.primaryobjects.com/CMS/Article145
Я лично исследовал много для этого решения, и лучший, который я мог найти, на самом деле из "проверки браузера"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();я переписал переменные, так что это более "человек" читаемый, но он делает работу лучше, чем ожидалось.
код:
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
короче говоря, вы можете сделать так
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"используйте функцию выше, чтобы получить доменное имя
Ну, делать с помощью регулярного выражения будет намного проще:
mainUrl = "http://www.mywebsite.com/mypath/to/folder"; urlParts = /^(?:\w+\:\/\/)?([^\/]+)(.*)$/.exec(mainUrl); host = Fragment[1]; // www.mywebsite.com
попробуйте ниже код для точного доменного имени с помощью 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"); }
Comments