我想仅匹配URL的根,而不是文本字符串中的整个URL。鉴于:
http://www.youtube.com/watch?v=ClkQA2Lb_iE
http://youtu.be/ClkQA2Lb_iE
http://www.example.com/12xy45
http://example.com/random
我想让最后两个实例解析为www.example.com
或example.com
域。
我听说正则表达式很慢,这将是我在页面上的第二个正则表达式,所以如果有没有正则表达式,请告诉我。
我正在寻找此解决方案的JS / jQuery版本。
答案 0 :(得分:277)
不使用正则表达式的巧妙技巧:
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;
}
答案 1 :(得分:242)
我建议使用npm包psl (Public Suffix List)。 "公共后缀列表"是一个包含所有有效域名后缀和规则的列表,不仅包括国家/地区代码顶级域名,还包括将被视为根域的unicode字符(即www.食狮。公司.cn,bckobe.jp等。 )。阅读更多相关信息here。
尝试:
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"));

无论是协议还是端口号,您都可以提取域名。这是一个非常简化的非正则表达式解决方案,所以我认为这样做。
*感谢@Timmerz,@ renoirb,@ irineez,@ BigDong,@ ra00l,@ ilikeBeansTacos,@ CharlesRobertson的建议! @ ross-allen,谢谢你报告这个错误!
答案 2 :(得分:110)
试试这个:
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
答案 3 :(得分:83)
无需解析字符串,只需将您的网址作为参数传递给URL
constructor:
var url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
var hostname = (new URL(url)).hostname;
assert(hostname === 'www.youtube.com');
答案 4 :(得分:36)
解析URL可能很棘手,因为您可以拥有端口号和特殊字符。因此,我建议使用类似parseUri的内容为您执行此操作。我怀疑性能将成为一个问题,除非您正在解析数百个URL。
答案 5 :(得分:14)
我尝试使用Given解决方案,选择的解决方案对我的目的来说太过分了,“创造一个元素”让我感到困惑。
还没有为URL中的Port做好准备。我希望有人发现它很有用
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"
}
答案 6 :(得分:13)
如果你最终在这个页面上,并且你正在寻找URL的最佳REGEX,试试这个:
^(?:https?:)?(?:\/\/)?([^\/\?]+)
https://regex101.com/r/pX5dL9/1
适用于没有http://的网址,带http的https,只有//并且不会抓取路径和查询路径。
祝你好运
答案 7 :(得分:7)
URL.hostname
来提高可读性在Babel时代,最干净,最简单的解决方案是使用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"));
URL.hostname
是URL API的一部分,除IE(caniuse)以外的所有主流浏览器均支持:
使用此解决方案还将使您能够访问其他URL properties and methods。例如,如果您还想提取URL的pathname或query string params,这将很有用。
URL.hostname
比使用anchor solution或parseUri更快。但是,它仍然比gilly3's regex慢得多:
const getHostnameFromRegex = (url) => {
// run against regex
const matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
// extract hostname (will be null if no match is found)
return matches && matches[1];
}
// tests
console.log(getHostnameFromRegex("https://stackoverflow.com/questions/8498592/extract-hostname-name-from-string/"));
console.log(getHostnameFromRegex("https://developer.mozilla.org/en-US/docs/Web/API/URL/hostname"));
在此jsPerf
上进行测试如果您需要处理大量URL(性能是一个重要因素),建议您改用此解决方案。否则,请选择URL.hostname
以提高可读性。
答案 8 :(得分:5)
new URL(url).host
答案 9 :(得分:3)
这不是一个完整的答案,但以下代码可以帮助您:
function myFunction() {
var str = "https://www.123rf.com/photo_10965738_lots-oop.html";
matches = str.split('/');
return matches[2];
}
我希望有人能比我的更快地创建代码。它也有助于改善自我。
答案 10 :(得分:2)
今天正在寻找解决这个问题的方法。上述答案似乎都不满足。我想要一个可以是单线程的解决方案,没有条件逻辑,也不需要包含在函数中。
在这里,我想出了什么,似乎工作得非常好:
hostname="http://www.example.com:1234" hostname.split("//").slice(-1)[0].split(":")[0].split('.').slice(-2).join('.') // gives "example.com"乍一看可能看起来很复杂,但它的工作非常简单;关键是使用' slice(-n)'在几个地方必须从分割数组的 end 中拉出好的部分(和[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('.')
答案 11 :(得分:2)
online with jquery
$('<a>').attr('href', document.location.href).prop('hostname');
答案 12 :(得分:2)
此解决方案提供您的答案以及其他属性。不需要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
}
答案 13 :(得分:2)
这里是jQuery one-liner:
$('<a>').attr('href', url).prop('hostname');
答案 14 :(得分:2)
好的,我知道这是一个老问题,但我制作了一个超级高效的网址解析器,所以我想我会分享它。
正如您所看到的,函数的结构非常奇怪,但它的效率却很高。没有使用原型函数,字符串不会被多次迭代,并且不会处理超过必要的字符。
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;
}
答案 15 :(得分:2)
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];
}
以上代码将成功解析以下示例网址的主机名:
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
https://www.another.eu/folder/page.html?q=1 another.eu
答案 16 :(得分: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]+.)/,"");
}
答案 17 :(得分:1)
我亲自为这个解决方案进行了很多研究,而我能找到的最好的解决方案实际上来自CloudFlare&#34;浏览器检查&#34;:
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();
我改写了变量,所以它更像是人类&#34;可读,但它的工作比预期更好。
答案 18 :(得分:1)
好吧,使用正则表达式会容易得多:
//Set up the dialog box
$("#myDialog").dialog({
autoOpen : false,
modal : true,
title : "A Dialog Box"
});
//Open the dialog box when the button is clicked.
$('#clickMe').click(function() {
$("#myDialog").dialog("open");
});
$(document).on('click', '#myDialog .ui-dialog-titlebar-close', function (e) {
e.preventDefault()
alert('you clicked the x!');
});
答案 19 :(得分:1)
// 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]+.)/,"");
}
答案 20 :(得分:1)
import URL from 'url';
const pathname = URL.parse(url).path;
console.log(url.replace(pathname, ''));
这同时照顾了两个协议。
答案 21 :(得分:0)
简而言之,你可以这样做
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"
使用上述功能获取域名
答案 22 :(得分:0)
Parse-Urls似乎是具有最可靠模式的JavaScript库
以下是这些功能的简要介绍:
Chapter 1. Normalize or parse one URL
Chapter 3. Extract URIs with certain names
Chapter 4. Extract all fuzzy URLs
答案 23 :(得分:-1)
代码:
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 :(得分:-1)
parse-domain-一个非常可靠的轻量级库
npm install parse-domain
const { fromUrl, parseDomain } = require("parse-domain");
示例1
parseDomain(fromUrl("http://www.example.com/12xy45"))
{ type: 'LISTED',
hostname: 'www.example.com',
labels: [ 'www', 'example', 'com' ],
icann:
{ subDomains: [ 'www' ],
domain: 'example',
topLevelDomains: [ 'com' ] },
subDomains: [ 'www' ],
domain: 'example',
topLevelDomains: [ 'com' ] }
示例2
parseDomain(fromUrl("http://subsub.sub.test.ExAmPlE.coM/12xy45"))
{ type: 'LISTED',
hostname: 'subsub.sub.test.example.com',
labels: [ 'subsub', 'sub', 'test', 'example', 'com' ],
icann:
{ subDomains: [ 'subsub', 'sub', 'test' ],
domain: 'example',
topLevelDomains: [ 'com' ] },
subDomains: [ 'subsub', 'sub', 'test' ],
domain: 'example',
topLevelDomains: [ 'com' ] }
为什么?
根据用例和容量,我强烈建议您自己使用正则表达式或其他字符串操作方法来解决此问题。此问题的核心是您需要了解所有gtld and cctld suffixes才能正确地将url字符串解析为域和子域,这些后缀会定期更新。这是一个已解决的问题,不是您要解决的问题(除非您是google之类的人)。除非您一时需要主机名或域名,否则不要尝试从中解析出自己的方式。
答案 25 :(得分:-1)
function getHostName(url) {
const urlStart: string = url.includes('//www.') ? '//www.' : '//';
return url.substring(url.indexOf(urlStart) + urlStart.length).split('/')[0];
};
console.log(getHostName('https://stackoverflow.com/questions')) // stackoverflow.com
console.log(getHostName('stackoverflow.com/questions')) // stackoverflow.com
答案 26 :(得分:-2)
我的代码如下所示。 正则表达式可以有多种形式,这是我的测试用例 我认为它更具扩展性。
function extractUrlInfo(url){
let reg = /^((?<protocol>http[s]?):\/\/)?(?<host>((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])|[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)))(\:(?<port>[0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5]))?$/
return reg.exec(url).groups
}
var url = "https://192.168.1.1:1234"
console.log(extractUrlInfo(url))
var url = "https://stackoverflow.com/questions/8498592/extract-hostname-name-from-string"
console.log(extractUrlInfo(url))
答案 27 :(得分:-6)
使用regex
尝试使用以下代码获取确切的域名String line =&#34; http://www.youtube.com/watch?v=ClkQA2Lb_iE&#34 ;;
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");
}