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 |
+----------------------+------------+
関連:
私はかつて働いていた会社のためにそのような正規表現を書く必要がありました。解決策はこれでした:
正規表現の例:
.*([^\.]+)(com|net|org|info|coop|int|co\.uk|org\.uk|ac\.uk|uk|__and so on__)$
これは非常にうまく機能し、de.comや友人などの奇妙で非公式のトップレベルにもマッチしました。
利点:
もちろん、このソリューションの欠点は次のとおりです。
/^(?:www\.)?(.*?)\.(?:com|au\.uk|co\.in)$/
ドメイン名を正確に抽出することは、主にドメイン拡張子に2つの部分(.com.auや.co.ukなど)が含まれ、サブドメイン(プレフィックス)がある場合とない場合があるため、非常に注意が必要です。すべてのドメイン拡張子をリストすることは、これらが何百もあるためオプションではありません。たとえば、EuroDNS.comには800を超えるドメイン名拡張子がリストされています。
したがって、「parse_url()」とドメイン拡張に関するいくつかの観察を使用して、URLコンポーネントとドメイン名を正確に抽出する短いphp関数を作成しました。機能は次のとおりです。
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の出力は次のようになります。
ご覧のとおり、ドメイン名と拡張子のないドメイン名は、関数に表示されるURLが何であれ一貫して抽出されます。
これが役立つことを願っています。
ライブラリは知りませんが、ドメイン名の文字列操作は簡単です。
難しいのは、名前が第2レベルか第3レベルかを知ることです。このためには、管理するデータファイルが必要です(たとえば、.ukは常に第3レベルではなく、一部の組織(たとえば、bl.uk、jet.uk)は第2レベルに存在します)。
Mozillaの Firefoxのソース にはそのようなデータファイルがあります。Mozillaのライセンスを確認して、再利用できるかどうかを確認してください。
2つの方法があります
分割を使用
次に、その文字列を解析するだけです
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
お役に立てれば
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」のような無効なURLをフィルタリングしません。
しかし、ほとんどの場合、それは仕事をします。
http://www.db.de/ または http://bbc.co.uk/のような多くのケースが存在するため、TLDリストを使用して比較することはできません。 ドメインdb.de
(正しい)およびco.uk
(間違った)として正規表現によって解釈されます。
しかし、それでもリストにSLDが含まれていない場合は成功しません。 http://big.uk.com/ や http://www.uk.com/ のようなURLは両方ともuk.com
(最初のドメインはbig.uk.comです)。
そのため、すべてのブラウザーはMozillaのパブリックサフィックスリストを使用します。
https://en.wikipedia.org/wiki/Public_Suffix_List
次のURLからインポートすることで、コードで使用できます。
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
基本的に、あなたが望むのは:
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
名前の最後から2番目の部分を見るだけでドメインの99%が適切に一致するため、常に変化する正規表現を作成する必要はありません。
(co|com|gov|net|org)
これらのいずれかである場合、3つのドットを一致させる必要があります。それ以外の場合は2.です。さて、私の正規表現ウィザードは他のSO'erのものとは一致しないので、これを達成するために私が見つけた最良の方法は、すでにパスを削除したと仮定して、いくつかのコードを使用することです:
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)を追加するだけです。
私は誰かが正規表現だけを使用してこのすべてを行うのを見てみたい、それは可能だと確信しています。
/[^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が正しく一致しない
この(。)(。*?)(。)を使用して、リーディングポイントとエンドポイントを抽出します。簡単ですね。
これはどのように
=((?:(?:(?:http)s?:)?\/\/)?(?:(?:[a-zA-Z0-9]+)\.?)*(?:(?:[a-zA-Z0-9]+))\.[a-zA-Z0-9]{2,3})
(パターンの最後に「\ /」を追加することもできます
パラメータとして渡されたURLを削除することが目的の場合、次のように最初の文字として等号を追加できます。
=((?:(?:( ?: http)s?:)?//)?(?:(?:[a-zA-Z0-9] +)。?)*(?:(?:[ a-zA-Z0-9] +))。[a-zA-Z0-9] {2,3} /)
そして「/」に置き換えます
この例の目標は、表示される形式に関係なく、ドメイン名を削除することです(つまり、xss攻撃を回避するために、URLパラメータにドメイン名が含まれないようにします)。
削除できるドメインプレフィックスとサフィックスのリストが必要です。例えば:
プレフィックス:
www.
接尾辞:
.com
.co.in
.au.uk
特定の目的のために、私は昨日このクイックPython関数を実行しました。URLからドメインを返します。高速で、入力ファイルをリストするものを必要としません。しかし、すべてのケースがありますが、単純なテキストマイニングスクリプトに必要な仕事を本当に果たします。
出力は次のようになります。
http://www.google.co.uk => google.co.uk
http://24.media.tumblr.com/tumblr_m04s34rqh567ij78k_250.gif => 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 ''
かなりうまくいくようです。
ただし、出力のドメイン拡張子を削除するには、希望どおりに変更する必要があります。
私は質問が正規表現のソリューションを求めていることを知っていますが、すべての試みですべてをカバーすることはできません
このメソッドをPython)で記述することにしました。これは、サブドメイン(www.mydomain.co.uk)を持ち、www.mail.yahoo.com
のような複数レベルのサブドメインを持たないURLでのみ動作します
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:])}
したがって、使用できる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');