如何从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 |
+----------------------+------------+
相关:
答案 0 :(得分:39)
我曾经为我工作过的公司写过这样的正则表达式。解决方案是:
示例正则表达式:
.*([^\.]+)(com|net|org|info|coop|int|co\.uk|org\.uk|ac\.uk|uk|__and so on__)$
这非常有效,并且还与 de.com 和朋友等奇怪的,非正式的顶层相匹配。
好处:
这个解决方案的缺点当然是:
答案 1 :(得分:12)
/^(?:www\.)?(.*?)\.(?:com|au\.uk|co\.in)$/
答案 2 :(得分:8)
准确提取域名可能非常棘手,主要是因为域扩展可以包含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的输出如下:
如您所见,无论提供给该功能的网址如何,都会一直提取没有扩展名的域名和域名。
我希望这会有所帮助。
答案 3 :(得分:6)
聚会晚了一点,但是:
const urls = [
'www.abc.au.uk',
'https://github.com',
'http://github.ca',
'https://www.google.ru',
'http://www.google.co.uk',
'www.yandex.com',
'yandex.ru',
'yandex'
]
urls.forEach(url => console.log(url.replace(/.+\/\/|www.|\..+/g, '')))
答案 4 :(得分:4)
我不知道任何库,但域名的字符串操作很容易。
困难的部分是知道名字是在第二级还是第三级。为此,您需要一个您维护的数据文件(例如,对于.uk并不总是第三级,某些组织(例如bl.uk,jet.uk)存在于第二级)。
Mozilla的source of Firefox有这样的数据文件,请检查Mozilla许可,看看是否可以重复使用。
答案 5 :(得分:4)
有两种方式
使用拆分
然后只解析该字符串
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];
使用正则表达式
var r = /:\/\/(.[^/]+)/;
"http://stackoverflow.com/questions/5343288/get-url".match(r)[1]
=> stackoverflow.com
希望这有帮助
答案 6 :(得分:3)
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])
此代码不保证可以与所有网址一起使用,也不会过滤那些语法正确但无效的例如“example.uk”。
然而,在大多数情况下它会完成这项任务。
答案 7 :(得分:2)
不使用TLD列表进行比较是不可能的,因为它们存在许多案例,例如http://www.db.de/或http://bbc.co.uk/,将由正则表达式解释为域db.de
(正确)和co.uk
(错误的)。
但即便如此,如果您的列表也不包含SLD,您将无法取得成功。 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
答案 8 :(得分:2)
基本上,你想要的是:
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%的域将被正确匹配:
(co|com|gov|net|org)
如果是其中之一,那么你需要匹配3个点,否则2.简单。现在,我的正则表达式魔法与其他一些SO'ers的不相符,所以我发现实现这一点的最好方法是使用一些代码,假设你已经脱离了这条道路:
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)添加到正则表达式。
我很乐意看到有人只使用正则表达式完成所有这些操作,我确信这是可能的。
答案 9 :(得分:1)
/[^w{3}\.]([a-zA-Z0-9]([a-zA-Z0-9\-]{0,65}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}/gim
使用此javascript正则表达式忽略www和跟随点,同时保持域完整。也适当地匹配没有www和cc tld
答案 10 :(得分:0)
您能否只查找 .com(或其他)之前的单词(其他列表的顺序与频率相反,请参阅 here
并取第一个匹配组 即
window.location.host.match(/(\w|-)+(?=(\.(com|net|org|info|coop|int|co|ac|ie|co|ai|eu|ca|icu|top|xyz|tk|cn|ga|cf|nl|us|eu|de|hk|am|tv|bingo|blackfriday|gov|edu|mil|arpa|au|ru)(\.|\/|$)))/g)[0]
您可以通过将此行复制到任何选项卡上的开发人员控制台来测试它
此示例适用于以下情况:
答案 11 :(得分:0)
我知道这个问题正在寻找正则表达式解决方案,但是在所有尝试中它都无法涵盖所有问题
我决定用Python编写此方法,该方法仅适用于具有子域(即www.mydomain.co.uk)的网址,而不适用于像www.mail.yahoo.com
这样的多层子域
def urlextract(url):
url_split=url.split(".")
if len(url_split) <= 2:
raise Exception("Full url required with subdomain:",url)
return {'subdomain': url_split[0], 'domain': url_split[1], 'suffix': ".".join(url_split[2:])}
答案 12 :(得分:0)
这是怎么回事?
=((?:(?:(?:http)s?:)?\/\/)?(?:(?:[a-zA-Z0-9]+)\.?)*(?:(?:[a-zA-Z0-9]+))\.[a-zA-Z0-9]{2,3})
(您可能希望添加&#34; \ /&#34;到模式结束
如果你的目标是摆脱作为参数传递的网址,你可以添加等号作为第一个字符,例如:
=(?(:( :( ?: HTTP)S:?)//)?(?:(?:[A-ZA-Z0-9] +)。?)*(:( ?:[A-ZA-Z0-9] +))[A-ZA-Z0-9] {2,3} /)
并替换为&#34; /&#34;
此示例的目标是删除任何域名,无论其出现何种形式。 (即确保url参数不包含域名以避免xss攻击)
答案 13 :(得分:0)
使用它 (。)(。*?)(。) 然后只提取前导点和终点。 容易,对吧?
答案 14 :(得分:0)
出于某种目的,我昨天做了这个快速的Python函数。它从URL返回域。它很快,不需要任何输入文件列表的东西。但是,我并不假装它在所有情况下都能正常工作,但它确实完成了我为简单的文本挖掘脚本所需的工作。
输出如下:
http://www.google.co.uk =&gt; google.co.uk
http://24.media.tumblr.com/tumblr_m04s34rqh567ij78k_250.gif =&gt; tumblr.com
def getDomain(url):
parts = re.split("\/", url)
match = re.match("([\w\-]+\.)*([\w\-]+\.\w{2,6}$)", parts[2])
if match != None:
if re.search("\.uk", parts[2]):
match = re.match("([\w\-]+\.)*([\w\-]+\.[\w\-]+\.\w{2,6}$)", parts[2])
return match.group(2)
else: return ''
似乎工作得很好。
但是,必须修改它以根据需要删除输出上的域扩展名。
答案 15 :(得分:0)
因此,如果你只有一个字符串而不是window.location,你可以使用...
String.prototype.toUrl = function(){
if(!this && 0 < this.length)
{
return undefined;
}
var original = this.toString();
var s = original;
if(!original.toLowerCase().startsWith('http'))
{
s = 'http://' + original;
}
s = this.split('/');
var protocol = s[0];
var host = s[2];
var relativePath = '';
if(s.length > 3){
for(var i=3;i< s.length;i++)
{
relativePath += '/' + s[i];
}
}
s = host.split('.');
var domain = s[s.length-2] + '.' + s[s.length-1];
return {
original: original,
protocol: protocol,
domain: domain,
host: host,
relativePath: relativePath,
getParameter: function(param)
{
return this.getParameters()[param];
},
getParameters: function(){
var vars = [], hash;
var hashes = this.original.slice(this.original.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
};};
如何使用。
var str = "http://en.wikipedia.org/wiki/Knopf?q=1&t=2";
var url = str.toUrl;
var host = url.host;
var domain = url.domain;
var original = url.original;
var relativePath = url.relativePath;
var paramQ = url.getParameter('q');
var paramT = url.getParamter('t');
答案 16 :(得分:0)
您需要一个可以删除哪些域名前缀和后缀的列表。例如:
前缀:
www.
后缀:
.com
.co.in
.au.uk
答案 17 :(得分:-1)
只是为了知识:
'http://api.livreto.co/books'.replace(/^(https?:\/\/)([a-z]{3}[0-9]?\.)?(\w+)(\.[a-zA-Z]{2,3})(\.[a-zA-Z]{2,3})?.*$/, '$3$4$5');
# returns livreto.co
答案 18 :(得分:-1)
/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/i
答案 19 :(得分:-1)
#!/usr/bin/perl -w
use strict;
my $url = $ARGV[0];
if($url =~ /([^:]*:\/\/)?([^\/]*\.)*([^\/\.]+)\.[^\/]+/g) {
print $3;
}